Swiftsuspenders2 是一个基于元数据(metadata)的IOC(控制反转,inversion of control)的AS3的解决方案。反转控制又被称依赖注射(Dependency Injection),也就是将依赖先剥离,然后在适当时候再注射进入。它是一种降低耦合度的程序设计模式其核心原则是高层模块不应依赖于低层模块,他们都应该依赖于抽象。抽象不依赖细节,细节依赖抽象,它通过将对象的创建过程解耦出来来降低对象间的依赖关系。IOC的设计目标是不直接创建对象,但是描述对象的创建方式,在代码中不直接链接对象和服务,通过配置的方式描述哪一种组件需要哪一些服务,然后在ioc容器中负责自动将对象服务和需要使用他们的地方进行链接。下面我们通过一个简单的例子,先了解一下如何利用依赖注入进行解耦。

关于依赖注入

当我们需要进行一个发送消息或者邮件的流程时 我们可能会写如下代码(demo0):

 package  demo0
{
/**
* ...
* @author titi
*/
public class Mail
{
public var Title:String; public function Send():void
{
trace(" Send Mail:"+Title);
} public function Mail(title:String)
{
Title = title;
} }   }
  
  
package demo0
{
/**
* ...
* @author titi
*/
public class Notification
{
private var _email:Mail;
public function Notification()
{
_email = new Mail("测试邮件1");
} public function PromotionalNotification():void
{
_email.Send();
}
}   }
  
  
package demo0
{
import flash.display.Sprite;
import flash.events.Event; /**
* ...
* @author titi
*/
public class Main0 extends Sprite
{ public function Main0():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
} private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
var notificatoin:Notification = new Notification();
notificatoin.PromotionalNotification();
} }   }

这里Mail和其控制器Notification 是直接关联的,控制器依赖Mail对象。通过抽象Mail 可以进行解耦降低Notification和Mail的耦合度。

 package demo1
{ /**
* ...
* @author titi
*/
public interface IMsg
{
function set Title(value:String):void; function get Title():String; function Send():void;
} }
  
package demo1
{
/**
* ...
* @author titi
*/
public class Mail implements IMsg
{
public var _Title:String; public function Send():void
{
trace(" Send Mail:"+Title);
} public function Mail(title:String)
{
_Title = title;
} /* INTERFACE demo1.IMsg */ public function set Title(value:String):void
{
_Title = value;
} public function get Title():String
{
return _Title;
} } } package demo1
{
/**
* ...
* @author titi
*/
public class Notification
{
private var _email:IMsg; public function PromotionalNotification():void
{
_email.Send();
}
} }

抽象后 可以通过四种方式(注入点) 在Notification 中注入IMail对应的具体的Mail 分别是

1、构造函数注入

 package  demo1
{
/**
* ...
* @author titi
*/
public class Notification
{
private var _email:IMsg;
public function Notification(email:IMsg)
{
_email = email;
} public function PromotionalNotification():void
{
_email.Send();
}
} }

2、方法注入

 package  demo1
{
/**
* ...
* @author titi
*/
public class Notification3
{
private var _email:IMsg; public function Notification3()
{ } public function PromotionalNotification(mail:IMsg):void
{
mail.Send();
}
} }

3、属性注入

 package  demo1
{
/**
* ...
* @author titi
*/
public class Notification2
{
private var _email:IMsg; public function Notification2()
{ } public function PromotionalNotification():void
{
_email.Send();
} //提供供外部注入Set属性
public function set email(value:IMsg):void
{
_email = value;
}
} }

4、变量注入

 package  demo1
{
/**
* ...
* @author titi
*/
public class Notification4
{
/**
* 公共变量提供抽象注入
*/
public var _email:IMsg; public function Notification4()
{ } public function PromotionalNotification():void
{
_email.Send();
} } }

在Demo1中我们用如下代码来进行显示的抽象注入:

 package demo1
{
import flash.display.Sprite;
import flash.events.Event; /**
* ...
* @author titi
*/
public class Main1 extends Sprite
{ public function Main1():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
} private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point //构造依赖
var notificatoin:Notification = new Notification(new Mail("测试邮件1"));
notificatoin.PromotionalNotification();
//属性依赖
var notificatoin2:Notification2 = new Notification2();
notificatoin2.email = new Mail("测试邮件2");
notificatoin2.PromotionalNotification();
//方法依赖
var notificatoin3:Notification3 = new Notification3();
notificatoin3.PromotionalNotification(new Mail("测试邮件3"));
//变量依赖
var notificatoin4:Notification4 = new Notification4();
notificatoin4._email=new Mail("测试邮件4")
notificatoin4.PromotionalNotification();
} } }

执行后输出如下:

  Send Mail:测试邮件1
Send Mail:测试邮件2
Send Mail:测试邮件3
Send Mail:测试邮件4

上面2个demo大致说明了如何通过依赖注入对现有的逻辑进行解耦,接下来我们用Swiftsuspenders2框架来快速实现上述的demo1作为对Swiftsuspenders2框架的入门详细参考如下demo2代码。

 package  demo2
{
/**
* ...
* @author titi
*/ [Inject(name="email1")]
public class Notification
{
private var _email:IMsg;
public function Notification(email:IMsg)
{
_email = email;
} public function PromotionalNotification():void
{
_email.Send();
}
} } package demo2
{
/**
* ...
* @author titi
*/
public class Notification2
{
private var _email:IMsg; public function Notification2()
{ } public function PromotionalNotification():void
{
_email.Send();
} public function get email():IMsg
{
return _email;
} [Inject(name="email2")]
public function set email(value:IMsg):void
{
_email = value;
}
} }
package demo2
{
/**
* ...
* @author titi
*/
public class Notification3
{
private var _email:IMsg; public function Notification3()
{ } [Inject(name = "email3")]
public function inject(mail:IMsg):void
{
_email = mail;
} public function PromotionalNotification():void
{
_email.Send();
}
} } package demo2
{
/**
* ...
* @author titi
*/
public class Notification4
{
/**
* 公共变量提供抽象注入
*/ [Inject(name = "email4")]
public var _email:IMsg; public function Notification4()
{ } public function PromotionalNotification():void
{
_email.Send();
} } } package demo2
{
import flash.display.Sprite;
import flash.events.Event;
import org.swiftsuspenders.Injector; /**
* ...
* @author titi
*/
public class Main2 extends Sprite
{ public function Main2():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
} private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point //申明注入器
var injector:Injector = new Injector(); injector.map(IMsg, "email1").toValue(new Mail("测试邮件1"));
injector.map(IMsg, "email2").toValue(new Mail("测试邮件2"));
injector.map(IMsg, "email3").toValue(new Mail("测试邮件3"));
injector.map(IMsg, "email4").toValue(new Mail("测试邮件4")); (injector.instantiateUnmapped(Notification) as Notification).PromotionalNotification();
(injector.instantiateUnmapped(Notification2) as Notification2).PromotionalNotification();
(injector.instantiateUnmapped(Notification3) as Notification3).PromotionalNotification();
(injector.instantiateUnmapped(Notification4) as Notification4).PromotionalNotification();
} } }

Robotlegs2 学习笔记 -- SwiftSuspenders 2.x (1)的更多相关文章

  1. Robotlegs2 学习笔记 -- SwiftSuspenders 2.x (2)

    Swiftsuspenders2简介 Swiftsuspenders2是一个基于元数据(metadata)的IOC(控制反转,inversion of control)的AS3的解决方案.(对于元数据 ...

  2. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  3. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  4. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  5. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

  6. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  7. seaJs学习笔记2 – seaJs组建库的使用

    原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...

  8. CSS学习笔记

    CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...

  9. HTML学习笔记

    HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...

随机推荐

  1. Python装饰器通用样式

    装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值也是一个函数对象.它经常用于有切面需求的场景,比如:插入日志.性能测试.事务处理. ...

  2. KB975517 "The update does not apply to your system"

    https://www.manageengine.com/products//desktop-central/patch-management/Windows-Vista-Ultimate-Editi ...

  3. objective-c 下面int 和 NSData数据 互相转换的方法

    抄自这里 ; NSData *data = [NSData dataWithBytes: &i length: sizeof(i)]; int i; [data getBytes: & ...

  4. Linux IO调度器相关算法介绍(转)

    IO调度器(IO Scheduler)是操作系统用来决定块设备上IO操作提交顺序的方法.存在的目的有两个,一是提高IO吞吐量,二是降低IO响应时间.然而IO吞吐量和IO响应时间往往是矛盾的,为了尽量平 ...

  5. 用happen-before规则重新审视DCL(转)

    编写Java多线程程序一直以来都是一件十分困难的事,多线程程序的bug很难测试,DCL(Double Check Lock)就是一个典型,因此对多线程安全的理论分析就显得十分重要,当然这决不是说对多线 ...

  6. M2M

    1, M2M (数据算法模型) M2M是将数据从一台终端传送到另一台终端,也就是机器与机器(Machine to Machine)的对话.   M2M简介 但从广义上M2M可代表机器对机器(Machi ...

  7. 30天轻松学习javaweb_模拟tomcat

    运行 javac Server.java 编译java文件 执行 java Server 运行程序 在ie中输入 http://localhost:9999/ 打开模拟的服务程序 import jav ...

  8. 如何让python程序运行得更快

    原则1:不优化 原则2:不要优化那些不重要的部分(否则会降低可读性) 解决方案: 1. 使用函数,局部变量比全局变量快很多.尽量使用函数,如main() 2. 有选择性的消除属性访问. 如多用 fro ...

  9. C++学习17派生类的构造函数

    基类的构造函数不能被继承,在声明派生类时,对继承过来的成员变量的初始化工作也要由派生类的构造函数来完成.所以在设计派生类的构造函数时,不仅要考虑派生类新增的成员变量,还要考虑基类的成员变量,要让它们都 ...

  10. Java中的Property类

    Property是JAVA中的属性操作类,该类在java.util包中,它是HashTable的子类. 常用函数列表: l  Properties() n  构造函数 l  setProperty(S ...