SlideShare ist ein Scribd-Unternehmen logo
1 von 60
Downloaden Sie, um offline zu lesen
Interpreter 
implementation 
               of
                     Immad Naseer,
 advice weaving      Ryan Golbeck and
                     Gregor Kiczales.
                     University of British Columbia



                                                      1
Aspect­oriented programming (AOP)
provides linguistic mechanisms for modularizing 
crosscutting concerns.




                                                   2
Let's look at an example
Consider a web application with two kinds of users: administrators and regular 
users. We have to ensure that certain functionality can only be accessed by 
administrators and the rest only by a logged in user.




                                                                                  3
public class AdminController {
  public void handleCreateUser() {
    if(getLoggedInUser() == null || !getLoggedInUser().isAdmin())
      throw new AccessViolationException();

        // rest of code
    }

    public void handleRemoveUser() {
      if(getLoggedInUser() == null || !getLoggedInUser().isAdmin())
        throw new AccessViolationException();

        // rest of code
    }
}



             public class ProductController {
               public void handleBuyProduct() {
                 if(getLoggedInUser() == null)
                   throw new AccessViolationException();

                     // rest of code
                 }

                 public void handleSellProduct() {
                   if(getLoggedInUser() == null)
                     throw new AccessViolationException();

                     // rest of code
                 }
             }                                                        4
Access authorization
public aspect AccessAuthorization {

    before(): call(* *Controller.handle*(..))
          { ... }

    before(): call(* AdminController.handle*(..))
          { ... }

    after returning(User user):
                   call(void User.login(..)) &&
                   target(user)
          { ... }

    after returning(User user):
                   call(void User.logout(..)) &&
                   target(user)
          { ... }
}

                                                    5
Access authorization
public aspect AccessAuthorization {

    before(): call(* *Controller.handle*(..))
          { ... }

    before(): call(* AdminController.handle*(..))
          { ... }

    after returning(User user):
                   call(void User.login(..)) &&
                   target(user)
          { ... }

    after returning(User user):
                   call(void User.logout(..)) &&
                   target(user)
          { ... }
}

                                                    6
Access authorization
public aspect AccessAuthorization {

    before(): call(* *Controller.handle*(..))
          { ... }

    before(): call(* AdminController.handle*(..))
          { ... }

    after returning(User user):
                   call(void User.login(..)) &&
                   target(user)
          { ... }

    after returning(User user):
                   call(void User.logout(..)) &&
                   target(user)
          { ... }
}

                                                    7
Access authorization
public aspect AccessAuthorization {

    before(): call(* *Controller.handle*(..))
          { ... }

    before(): call(* AdminController.handle*(..))
          { ... }

    after returning(User user):
                   call(void User.login(..)) &&
                   target(user)
          { ... }

    after returning(User user):
                   call(void User.logout(..)) &&
                   target(user)
          { ... }
}

                                                    8
Terminology
                                            advice

before(): call(* User.login(..)) { ...
}



     pointcut                public void testProductBuy() {
                               u = User.find(“joe”);
                               u.login(“pass”);
                               ...
                               Product.buy(u, 12);
    join point shadows
                               ...
                             }

                                                         9
Terminology
                                            advice

before(): call(* User.login(..)) { ...
}



     pointcut                public void testProductBuy() {
                               u = User.find(“joe”);
                               u.login(“pass”);
                               ...
                               Product.buy(u, 12);
    join point shadows
                               ...
                             }

                                                         10
Advice weaving
coordinates execution of advice around, before or 
after applicable join points.




                                                     11
Rewriting based advice weaving
approaches rewrite the code    public void testProductBuy() {
at potentially advised join        u = User.find(“joe”);
point shadows (JPS) to             before_advice();
                                   u.login(“pass”);
invoke the advice (guarded         ...
by residual dynamic checks)        if (some_guard())
                                       some_other_before_advice();
                                   Product.buy(u, 12);
                                   }
                               }




                                                                     12
Rewriting based advice weaving
approaches rewrite the code    public void testProductBuy() {
at potentially advised join        u = User.find(“joe”);
point shadows (JPS) to             before_advice();
                                   u.login(“pass”);
invoke the advice (guarded         ...
by residual dynamic checks)        if (some_guard())
                                       some_other_before_advice();
                                   Product.buy(u, 12);
                                   }
                               }




                                                                     13
Rewriting based advice weaving
approaches rewrite the code    public void testProductBuy() {
at potentially advised join        u = User.find(“joe”);
point shadows (JPS) to             before_advice();
                                   u.login(“pass”);
invoke the advice (guarded         ...
by residual dynamic checks)        if (some_guard())
                                       some_other_before_advice();
                                   Product.buy(u, 12);
                                   }
                               }




                                                                     14
When (and how) to weave?
                                  interpreter 
compile time          load time        JIT




           runtime boundary




                                                 15
When (and how) to weave?
                                                          interpreter 
compile time                load time                          JIT

  eg. ajc



Rewrites the bytecode or source code of the application at compile time

+ no scanning and rewriting overhead at runtime

­ no “late weaving”

­ requires a global scan of the program ==> 
                               not suited for incremental development
                                                                          16
When (and how) to weave?
                                                 interpreter 
compile time              load time                   JIT

                          eg. ajc ltw



Rewrites the bytecode as part of class loading

+ allows “late weaving”

­ scanning and rewriting overhead at runtime ==>
           leads to slower applications startup

­ not suited for incremental development
                                                                17
When (and how) to weave?
                                           interpreter 
 compile time         load time                 JIT




Rewriting based weaving can impact application startup.




                                                          18
When (and how) to weave?
                                               interpreter 
 compile time            load time                  JIT




Non­rewriting based weaving can lead to faster startup but at the 
cost of reduced execution efficiency.

It has to do advice lookup and potential execution at each join point 
(note: NOT join point shadow!)

                                                                         19
When (and how) to weave?
                                              interpreter 
 compile time          load time                   JIT




VMs face a similar tradeoff between application startup and good 
steady state performance which is why they use the interpreter/JIT 
combination.




                                                                      20
When (and how) to weave?
                                               interpreter 
 compile time           load time                   JIT




We believe that having a combination of interpreter based non­
rewriting weaving and JIT based rewriting weaving might balance the 
startup/steady state efficiency trade off for aspect­oriented programs.




                                                                          21
When (and how) to weave?
                                                interpreter 
 compile time            load time                   JIT




In this talk, we focus on the interpreter part of the equation and present 
the design, implementation and evaluation of an interpreter based non­
rewriting weaver.




                                                                              22
Interpreter based weaving
­ should require minimum to no work from the static compiler

­ should require minimum work from the class loader

­ should “fail fast”

    (as data shows most join points are not advised)




                                                               23
An example

before(): call(* *Controller.handle*(..)) { ... }
                                                               advice
before(): call(* AdminController.handle*(..)) { ... }
after returning(User u): call(* User.login(..)
                         && target(u) { ... }
after returning(User u): call(* User.logout(..))
                         && target(u) { ... }



             invokevirtual   void   Database.establishConnection();
joinpoint    invokevirtual   void   PrintStream.println(..);
             invokevirtual   void   User.login(..);
stream
             invokevirtual   void   AdminController.handleCreateUser();
             invokevirtual   void   Logger.warn();
                                                                        24
An example
before(): call(* *Controller.handle*(..)) { ... }
before(): call(* AdminController.handle*(..)) { ... }
after returning(User u): call(* User.login(..)
                         && target(u) { ... }
after returning(User u): call(* User.logout(..))
                         && target(u) { ... }



             invokevirtual   void   Database.establishConnection();
             invokevirtual   void   PrintStream.println(..);
             invokevirtual   void   User.login(..);
             invokevirtual   void   AdminController.handleCreateUser();
             invokevirtual   void   Logger.warn();
                                                                    25
An example
before(): call(* *Controller.handle*(..)) { ... }
before(): call(* AdminController.handle*(..)) { ... }
after returning(User u): call(* User.login(..)
                        && target(u) { ... }
after returning(User u): call(* User.logout(..))
                        && target(u) { ... }



             invokevirtual   void   Database.establishConnection();
             invokevirtual   void   PrintStream.println(..);
             invokevirtual   void   User.login(..);
             invokevirtual   void   AdminController.handleCreateUser();
             invokevirtual   void   Logger.warn();
                                                                    26
Looking up advice at a join point
before(): call(* *Controller.handle*(..)) { ... }
before(): call(* AdminController.handle*(..)) { ... }
after returning(User u): call(* User.login(..)
                        && target(u) { ... }
after returning(User u): call(* User.logout(..))
                        && target(u) { ... }



             invokevirtual   void   Database.establishConnection();
             invokevirtual   void   PrintStream.println(..);
             invokevirtual   void   User.login(..);
             invokevirtual   void   AdminController.handleCreateUser();
             invokevirtual   void   Logger.warn();
                                                                    27
What property to dispatch on?
  before(): call(* *Controller.handle*(..)) { ... }
                                                               Static type of 
  before(): call(* AdminController.handle*(..)) { ... }
                                                               target type 
  after returning(User u): call(* User.login(..)               pattern
                             && target(u) { ... }
  after returning(User u): call(* User.logout(..))
                             && target(u) { ... }



                  invokevirtual   void   Database.establishConnection();
Static type of 
                  invokevirtual   void   PrintStream.println(..);
target            invokevirtual   void   User.login(..);
                  invokevirtual   void   AdminController.handleCreateUser();
                  invokevirtual   void   Logger.warn();
                                                                              28
What property to dispatch on?
 before(): call(* *Controller.handle*(..)) { ... }
                                                           Target name 
 before(): call(* AdminController.handle*(..)) { ... }
                                                           pattern
 after returning(User u): call(* User.login(..)
                         && target(u) { ... }
 after returning(User u): call(* User.logout(..))
                         && target(u) { ... }



              invokevirtual   void   Database.establishConnection();
Target name
              invokevirtual   void   PrintStream.println(..);
              invokevirtual   void   User.login(..);
              invokevirtual   void   AdminController.handleCreateUser();
              invokevirtual   void   Logger.warn();
                                                                      29
What property to dispatch on?
 before(): call(* *Controller.handle*(..)) { ... }
                                                           Return type 
 before(): call(* AdminController.handle*(..)) { ... }
                                                           pattern
 after returning(User u): call(* User.login(..)
                         && target(u) { ... }
 after returning(User u): call(* User.logout(..))
                         && target(u) { ... }



              invokevirtual   void   Database.establishConnection();
Return type
              invokevirtual   void   PrintStream.println(..);
              invokevirtual   void   User.login(..);
              invokevirtual   void   AdminController.handleCreateUser();
              invokevirtual   void   Logger.warn();
                                                                          30
We chose to dispatch on the 

static type of target (STT)
as it is available on all but one kind of join point.




                                                        31
Associating advice with types

Database
                  before(): call(* *Controller.handle*(..)) { ... }

PrintStream
                  before(): call(* AdminController.handle*(..)) { ... }
Logger
                  after returning(User u): call(* User.login(..)) && target(u) { ... }
User
                  after returning(User u): call(* User.logout(..)) && target(u) { ... }
AdminController




                                                                                     32
Associating advice with types

                  point to no advice
Database
                           before(): call(* *Controller.handle*(..)) { ... }

PrintStream
                           before(): call(* AdminController.handle*(..)) { ... }
Logger
                           after returning(User u): call(* User.login(..)) && target(u) { ... }
User
                           after returning(User u): call(* User.logout(..)) && target(u) { ... }
AdminController




                                                                                              33
Associating advice with types

Database
                  before(): call(* *Controller.handle*(..)) { ... }

PrintStream
                  before(): call(* AdminController.handle*(..)) { ... }
Logger
                  after returning(User u): call(* User.login(..)) && target(u) { ... }
User
                  after returning(User u): call(* User.logout(..)) && target(u) { ... }
AdminController




                                                                                     34
Associating advice with types

Database
                  before(): call(* *Controller.handle*(..)) { ... }

PrintStream
                  before(): call(* AdminController.handle*(..)) { ... }
Logger
                  after returning(User u): call(* User.login(..)) && target(u) { ... }
User
                  after returning(User u): call(* User.logout(..)) && target(u) { ... }
AdminController




                                                                                     35
When do we associate advice with 
types?
Database
                  before(): call(* *Controller.handle*(..)) { ... }

PrintStream
                  before(): call(* AdminController.handle*(..)) { ... }
Logger
                  after returning(User u): call(* User.login(..)) && target(u) { ... }
User
                  after returning(User u): call(* User.logout(..)) && target(u) { ... }
AdminController




                                                                                     36
When do we associate advice with 
types?
                  Type Pattern Tables (TPTs)
Database
                  before(): call(* *Controller.handle*(..)) { ... }

PrintStream
                  before(): call(* AdminController.handle*(..)) { ... }
Logger
                  after returning(User u): call(* User.login(..)) && target(u) { ... }
User
                  after returning(User u): call(* User.logout(..)) && target(u) { ... }
AdminController




                                                                                     37
Type Pattern Table Lists (TPTL)
are constructed for each type as it is loaded by the VM 
and point to all those TPTs whose type pattern match 
the type's name




                                                           38
*.tnp list

  Consider the following advice
  before(): execution(* *.main(String)) {
                ...
  }


   Wildcard STT type pattern   Non­wildcard target name pattern




                                                                  39
We store the list of applicable advice (or no advice) in a per method
shadow cache
so that we don't have to do the advice lookup when 
seeing the same join point shadow for the second time




                                                                        40
class AdminController

    TPT List 



                AdminController TPT        *Controller TPT


                before(): call(* ...        before(): call(* ...




                                   public void createUser(String userName, String password) {
createUser's shadow cache                ...
                                    4        invokevirtual Database.establishConnection();
    4 | NOT_INITIALIZED                  ...
  12 | NULL                         12      invokevirtual AdminController.initialize(String)
  18 | thunk for calling                 ...
         advice                     18      invokevirtual AdminController.handleCreateUser(...)
                                         ...
                                                                                             41
                                   }
Implementation
We implemented our design on JikesRVM 2.9.2 including 
support for

 ­ all five kinds of advice;
 
  ­ all kinds of join points except the initialization
     family of join points and advice­execution;
   
  ­ and only the singleton aspect instantiation model



We did not implement support for thisJoinPoint and inter­type 
declarations.

                                                                 42
Baseline compiler as interpreter model


The machine code generated by a baseline compiler looks like
the unrolling of the machine code that would be run by an 
interpreter.


We don't use any information that wouldn't be available to an 
interpreter.




                                                                 43
Evaluation setup
An optimized compiled instance of JikesRVM 2.9.2 but with the 
adaptive optimization system turned off.




                                                                 44
Measuring the performance of different paths




                                               45
Measuring the performance of different paths




                                               46
Measuring the performance of different paths




                                               47
Measuring the performance of different paths




                                               48
Measuring the performance of different paths




                                               49
Measuring the performance of different paths
The per join point overhead ranges from 28% to 462%; since most 
DJPs  are unadvised, the overhead will be closer to 28% more than 
90% of  the time




                                                                     50
Comparative micro benchmarks




      unadvised                before call




                                                 51
      cflow                    multiple advice
Comparative micro benchmarks




                  unadvised
                               52
Comparative micro benchmarks




                  before call
                                53
Comparative micro benchmarks




                before call in cflow
                                       54
Comparative micro benchmarks

 The startup times of the interpreter are shorter than for the ajc ltw by
  600­700ms  across most of the benchmarks.

  The infrastructure loading cost for ajc has not been factored out and is 
   loaded in the 600­700ms headstart.

 




                                                                            55
Comparative micro benchmarks




            before call – lots of classes
                                            56
Comparative micro benchmarks
The “lots of classes” benchmark shows that the ajc ltw has to do a 
noticeable amount of work for each class that is loaded.

This benchmark is also better approximates real life applications where 
not all the code that is loaded is run.




                                                                      57
Conclusion
We presented the design, implementation and evaluation of an 
interpreter based non­rewriting weaving approach.

Our evaluation clearly shows that interpreter based non­rewriting 
weaving is feasible to implement. 

While we cannot say anything definitive about the performance of the 
complete hybrid system, the evaluation results do suggest that the 
complete hybrid system might provide a good balance between faster 
startup and good steady state performance.



                                                                     58
Questions?




             59
60

Weitere ähnliche Inhalte

Was ist angesagt?

Cut your Dependencies - Dependency Injection at Silicon Valley Code Camp
Cut your Dependencies - Dependency Injection at Silicon Valley Code CampCut your Dependencies - Dependency Injection at Silicon Valley Code Camp
Cut your Dependencies - Dependency Injection at Silicon Valley Code CampTheo Jungeblut
 
Cut your Dependencies with Dependency Injection for East Bay.NET User Group
Cut your Dependencies with Dependency Injection for East Bay.NET User Group Cut your Dependencies with Dependency Injection for East Bay.NET User Group
Cut your Dependencies with Dependency Injection for East Bay.NET User Group Theo Jungeblut
 
Enforce Consistency through Application Infrastructure
Enforce Consistency through Application InfrastructureEnforce Consistency through Application Infrastructure
Enforce Consistency through Application InfrastructureFlorin Coros
 
2010 06-24 karlsruher entwicklertag
2010 06-24 karlsruher entwicklertag2010 06-24 karlsruher entwicklertag
2010 06-24 karlsruher entwicklertagMarcel Bruch
 
Lego For Engineers - Dependency Injection for LIDNUG (2011-06-03)
Lego For Engineers - Dependency Injection for LIDNUG (2011-06-03)Lego For Engineers - Dependency Injection for LIDNUG (2011-06-03)
Lego For Engineers - Dependency Injection for LIDNUG (2011-06-03)Theo Jungeblut
 

Was ist angesagt? (7)

Cut your Dependencies - Dependency Injection at Silicon Valley Code Camp
Cut your Dependencies - Dependency Injection at Silicon Valley Code CampCut your Dependencies - Dependency Injection at Silicon Valley Code Camp
Cut your Dependencies - Dependency Injection at Silicon Valley Code Camp
 
Cut your Dependencies with Dependency Injection for East Bay.NET User Group
Cut your Dependencies with Dependency Injection for East Bay.NET User Group Cut your Dependencies with Dependency Injection for East Bay.NET User Group
Cut your Dependencies with Dependency Injection for East Bay.NET User Group
 
Enforce Consistency through Application Infrastructure
Enforce Consistency through Application InfrastructureEnforce Consistency through Application Infrastructure
Enforce Consistency through Application Infrastructure
 
2010 06-24 karlsruher entwicklertag
2010 06-24 karlsruher entwicklertag2010 06-24 karlsruher entwicklertag
2010 06-24 karlsruher entwicklertag
 
Dynamic virtual evironments
Dynamic virtual evironmentsDynamic virtual evironments
Dynamic virtual evironments
 
Vaadin7
Vaadin7Vaadin7
Vaadin7
 
Lego For Engineers - Dependency Injection for LIDNUG (2011-06-03)
Lego For Engineers - Dependency Injection for LIDNUG (2011-06-03)Lego For Engineers - Dependency Injection for LIDNUG (2011-06-03)
Lego For Engineers - Dependency Injection for LIDNUG (2011-06-03)
 

Andere mochten auch

Andere mochten auch (6)

Technical application of nonwoven
Technical application of nonwovenTechnical application of nonwoven
Technical application of nonwoven
 
Kidswear categories
Kidswear categories Kidswear categories
Kidswear categories
 
Nonwovens & its applications
Nonwovens & its applicationsNonwovens & its applications
Nonwovens & its applications
 
Classification of textiles
Classification of textilesClassification of textiles
Classification of textiles
 
Kidswear
KidswearKidswear
Kidswear
 
Some lessons of Weaving
Some lessons of WeavingSome lessons of Weaving
Some lessons of Weaving
 

Ähnlich wie AOP Weaving Techniques

JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?Doug Hawkins
 
Paradigmas de linguagens de programacao - aula#9
Paradigmas de linguagens de programacao - aula#9Paradigmas de linguagens de programacao - aula#9
Paradigmas de linguagens de programacao - aula#9Ismar Silveira
 
Pro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScriptPro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScriptSeok-joon Yun
 
Silicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsSilicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsAzul Systems, Inc.
 
Thomas braun dependency-injection_with_robo_guice-presentation-final
Thomas braun dependency-injection_with_robo_guice-presentation-finalThomas braun dependency-injection_with_robo_guice-presentation-final
Thomas braun dependency-injection_with_robo_guice-presentation-finalDroidcon Berlin
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksMongoDB
 
Async task, threads, pools, and executors oh my!
Async task, threads, pools, and executors oh my!Async task, threads, pools, and executors oh my!
Async task, threads, pools, and executors oh my!Stacy Devino
 
Under the Hood: Using Spring in Grails
Under the Hood: Using Spring in GrailsUnder the Hood: Using Spring in Grails
Under the Hood: Using Spring in GrailsBurt Beckwith
 
TWINS: OOP and FP - Warburton
TWINS: OOP and FP - WarburtonTWINS: OOP and FP - Warburton
TWINS: OOP and FP - WarburtonCodemotion
 
SOLID - Not Just a State of Matter, It's Principles for OO Propriety
SOLID - Not Just a State of Matter, It's Principles for OO ProprietySOLID - Not Just a State of Matter, It's Principles for OO Propriety
SOLID - Not Just a State of Matter, It's Principles for OO ProprietyChris Weldon
 

Ähnlich wie AOP Weaving Techniques (20)

SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
 
Paradigmas de linguagens de programacao - aula#9
Paradigmas de linguagens de programacao - aula#9Paradigmas de linguagens de programacao - aula#9
Paradigmas de linguagens de programacao - aula#9
 
E:\Plp 2009 2\Plp 9
E:\Plp 2009 2\Plp 9E:\Plp 2009 2\Plp 9
E:\Plp 2009 2\Plp 9
 
Pro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScriptPro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScript
 
Introduction to-java
Introduction to-javaIntroduction to-java
Introduction to-java
 
Silicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsSilicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM Mechanics
 
Annotation processing tool
Annotation processing toolAnnotation processing tool
Annotation processing tool
 
Modern c++
Modern c++Modern c++
Modern c++
 
JDK Power Tools
JDK Power ToolsJDK Power Tools
JDK Power Tools
 
CDI and Weld
CDI and WeldCDI and Weld
CDI and Weld
 
Gwt.create
Gwt.createGwt.create
Gwt.create
 
Thomas braun dependency-injection_with_robo_guice-presentation-final
Thomas braun dependency-injection_with_robo_guice-presentation-finalThomas braun dependency-injection_with_robo_guice-presentation-final
Thomas braun dependency-injection_with_robo_guice-presentation-final
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New Tricks
 
Async task, threads, pools, and executors oh my!
Async task, threads, pools, and executors oh my!Async task, threads, pools, and executors oh my!
Async task, threads, pools, and executors oh my!
 
Mattbrenner
MattbrennerMattbrenner
Mattbrenner
 
Under the Hood: Using Spring in Grails
Under the Hood: Using Spring in GrailsUnder the Hood: Using Spring in Grails
Under the Hood: Using Spring in Grails
 
TWINS: OOP and FP - Warburton
TWINS: OOP and FP - WarburtonTWINS: OOP and FP - Warburton
TWINS: OOP and FP - Warburton
 
SOLID - Not Just a State of Matter, It's Principles for OO Propriety
SOLID - Not Just a State of Matter, It's Principles for OO ProprietySOLID - Not Just a State of Matter, It's Principles for OO Propriety
SOLID - Not Just a State of Matter, It's Principles for OO Propriety
 
meet.js - QooXDoo
meet.js - QooXDoomeet.js - QooXDoo
meet.js - QooXDoo
 

Kürzlich hochgeladen

Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...itnewsafrica
 
Landscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdfLandscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdfAarwolf Industries LLC
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Kaya Weers
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...itnewsafrica
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observabilityitnewsafrica
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Jeffrey Haguewood
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024TopCSSGallery
 
Kuma Meshes Part I - The basics - A tutorial
Kuma Meshes Part I - The basics - A tutorialKuma Meshes Part I - The basics - A tutorial
Kuma Meshes Part I - The basics - A tutorialJoão Esperancinha
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...Nikki Chapple
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...amber724300
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...Karmanjay Verma
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkPixlogix Infotech
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesBernd Ruecker
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...BookNet Canada
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructureitnewsafrica
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...itnewsafrica
 

Kürzlich hochgeladen (20)

Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
 
Landscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdfLandscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdf
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024
 
Kuma Meshes Part I - The basics - A tutorial
Kuma Meshes Part I - The basics - A tutorialKuma Meshes Part I - The basics - A tutorial
Kuma Meshes Part I - The basics - A tutorial
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
JET Technology Labs White Paper for Virtualized Security and Encryption Techn...
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App Framework
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architectures
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
 

AOP Weaving Techniques