Uncommon Design Patterns

        STEFANO FAGO - 2003
Uncommon Design Patterns

G.O.F. Design Patterns are design tools
wide adopted by developers and architects working
with O...
Uncommon Design Patterns

The Patterns are:

    Null Object
●


    Encapsulated Context
●


    Role Object
●


    ISP ...
Null Object

It proposes the adoption of an object, in relation to a
given Type, to expresses the concept of NO
ACTION or ...
Null Object

Supposing some code:
           InfoList availableUnits = manager.getOperativeUnitFor(...);
   for (Iterator ...
Null Object

We can avoid this issue with Null Object
     InfoList getOperativeUnitFor(String nationCode, String areaCode...
Encapsulated Context

In complex systems, it becomes necessary to use
common data, with global visibility, such as
configu...
Encapsulated Context

Supposing to have different Component that need to
share common services such as Logging, Order
Mana...
Encapsulated Context

If the number of Common Services grow, we can
have a signature mess!
So we need a single object to e...
Role Object

On large size design is easy to deal with a modeling
problem: an element can plays different roles
depending ...
Role Object

Objective of the Role Object Pattern is to offer a
solution to the problem of roles thanks to a set of
Role O...
Role Object

We can use the simple example of Employee and
different roles that this element can plays!
interface Employee...
Role Object

Now we can define the Core Object and Role
Objects:
     class EmployeeCore implements Employee{
       priva...
Role Object

    class EmployeeRole implements Employee{

     private EmployeeCore core; ...
     String getName(){ retur...
Role Object

We can construct the complex object:
            EmployeeCore [] empls = new EmployeeCore[3];
            emp...
Role Object

Follow, the sample usage:
          Employee emp = manager.getEmployee(...);

          if (emp.hasRole(quot;...
ISP & Object Adaptation

Inspired by PEP 246 (Python Language)
any object might quot;embodyquot; a protocol:

         ada...
ISP & Object Adaptation

    We first define ad adaptable protocol then define
●

    the adapters and register them; at l...
ISP & Object Adaptation

    Define some target Contracts and Adapters:
●


     public interface Reader { public Object r...
ISP & Object Adaptation

    Define some Adaptable:
●


        public class Circle implements Shape, Adaptable{
         ...
Essence Pattern

This Design use a particular class identified as
Essence that encapsulates the basic properties for
the c...
Essence Pattern
Essence Pattern

    public class Server {
        public Server(ServerEssence essence) { ... }
        ... }


    public...
Upcoming SlideShare
Loading in …5
×

Uncommon Design Patterns

2,525 views

Published on

Some thoughts about unconventional Design Patterns... :-D

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,525
On SlideShare
0
From Embeds
0
Number of Embeds
18
Actions
Shares
0
Downloads
7
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Uncommon Design Patterns

  1. 1. Uncommon Design Patterns STEFANO FAGO - 2003
  2. 2. Uncommon Design Patterns G.O.F. Design Patterns are design tools wide adopted by developers and architects working with Object Oriented Technology and, on them, you may experience a wide literature. These Slides try to introduce some Design Pattern less visible but very practical!
  3. 3. Uncommon Design Patterns The Patterns are: Null Object ● Encapsulated Context ● Role Object ● ISP & Object Adaptation ● Essence ●
  4. 4. Null Object It proposes the adoption of an object, in relation to a given Type, to expresses the concept of NO ACTION or EMPTY ELEMENT, respecting the contract (the Interface) of the Type of which is a surrogate. The issue that you want to solve is to avoid the use of NULL/NIL in situations where it is necessary to return a reference to an Object, although there will be no processing.
  5. 5. Null Object Supposing some code: InfoList availableUnits = manager.getOperativeUnitFor(...); for (Iterator iterator = availableUnits.iterator(); iterator.hasNext();) { // do something with unit } to be able to processe without error we have to use a nullity check: if(availableUnits != null){ for (Iterator iterator = availableUnits.iterator(); iterator.hasNext();) { // do something with unit } }
  6. 6. Null Object We can avoid this issue with Null Object InfoList getOperativeUnitFor(String nationCode, String areaCode) { InfoList result = // ...seach for... // if there no Unit and Empty List is returned... result = new VoidInfoList(); return result; } so the code can became: InfoList availableUnits = manager.getOperativeUnitFor(...); for (Iterator iterator = availableUnits.iterator(); iterator.hasNext();) { // do something with unit }
  7. 7. Encapsulated Context In complex systems, it becomes necessary to use common data, with global visibility, such as configuration data. The use of global elements is a practice not recommended in Object Oriented Systems, and even if the GOF Singleton Pattern can offer a way out, its abuse can be detrimental.
  8. 8. Encapsulated Context Supposing to have different Component that need to share common services such as Logging, Order Management and recieve also specific messages. Every Component must have a method with signature: process(SomeMsg msg, OrdersManager ordMan, Logger log){ ... }
  9. 9. Encapsulated Context If the number of Common Services grow, we can have a signature mess! So we need a single object to encapsulate the different services without using global object but using injection on method... process(ProcessContext ctx){ Msg msg = ctx.getActualMsg(); ctx.log(...); ctx.processLastOrder(); ... }
  10. 10. Role Object On large size design is easy to deal with a modeling problem: an element can plays different roles depending on the context in which it is placed. The idea of Role can be developed from the concept of interface and use multiple inheritance to compose different roles: this approach can lead to an object unwieldy and difficult to manage!
  11. 11. Role Object Objective of the Role Object Pattern is to offer a solution to the problem of roles thanks to a set of Role Objects that are dynamically added or removed compared to a Core Object.
  12. 12. Role Object We can use the simple example of Employee and different roles that this element can plays! interface Employee: interface Employee{ String getName(); long getId(); boolean hasRole(String role); EmployeeRole getRole(String role); void removeRole(String role); void addRole(String role); }
  13. 13. Role Object Now we can define the Core Object and Role Objects: class EmployeeCore implements Employee{ private Map roles = ... public boolean hasRole(String role) { return roles.containsKey(role);} public EmployeeRole getRole(String role) {return (EmployeeRole) roles.get(role);} public void addRole(String role, EmployeeRole impl) {roles.put(role, impl);} public void removeRole(String role) {roles.remove(role); } ... }
  14. 14. Role Object class EmployeeRole implements Employee{ private EmployeeCore core; ... String getName(){ return core.getName(); } ... boolean hasRole(String role) { return core.hasRole(); } ... } class Director extends EmployeeRole{ Director(EmployeeCore core)...} class Buyer extends EmployeeRole{ Buyer(EmployeeCore core)...}
  15. 15. Role Object We can construct the complex object: EmployeeCore [] empls = new EmployeeCore[3]; empls[0] = new EmployeeCore(); empls[1] = new EmployeeCore(); empls[2] = new EmployeeCore(); Director d = new Director(empls[0]); empls[0].addRole(quot;directorquot;,d); Buyer b = new Buyer(empls[2]); empls[2].addRole(quot;buyerquot;,b); We can hide complex object with a manager: Employee emp = manager.getEmployee(...);
  16. 16. Role Object Follow, the sample usage: Employee emp = manager.getEmployee(...); if (emp.hasRole(quot;directorquot;)) { Director director = (Director)emp; ... } if (emp.hasRole(quot;buyerquot;)) { Buyer buyer = (Buyer)emp; ... }
  17. 17. ISP & Object Adaptation Inspired by PEP 246 (Python Language) any object might quot;embodyquot; a protocol: adapt(component, protocol[, default]) checks if component directly implements protocol ● checks if protocol knows how to adapt component ● else falls back to a registry of adapters indexed by ● type(component) [[or otherwise, e.g. by URI]] last ditch: returns default or raises an exception ●
  18. 18. ISP & Object Adaptation We first define ad adaptable protocol then define ● the adapters and register them; at last we use type to play ;-) Our simple protocol: ● public interface Adaptable { public Object adapt(Class targetType); }
  19. 19. ISP & Object Adaptation Define some target Contracts and Adapters: ● public interface Reader { public Object read(); } public interface Shape { public float area(); public void draw(); } public interface Writer { public void write(Object o); } public class ShapeReaderAdapter{ ... } public class ShapeWriterAdapter{...} Register Contracts with relative Adapters: ● AdapterRegistry.registerAdapter( Shape.class, Reader.class, ShapeReaderAdapter.class); AdapterRegistry.registerAdapter( Shape.class, Writer.class, ShapeWriterAdapter.class);
  20. 20. ISP & Object Adaptation Define some Adaptable: ● public class Circle implements Shape, Adaptable{ public float area() {... } public void draw() {...} public Object adapt(Class targetType) { return AdapterRegistry.getAdapter(this,targetType); } } Use Object Adaptation: ● Circle circle = new Circle(); Writer writer = (Writer) circle.adapt(Writer.class);
  21. 21. Essence Pattern This Design use a particular class identified as Essence that encapsulates the basic properties for the configuration and validation of the target Object. Once the object Essence is instantiated, the validation of the elements is fired and only if this operation has successfully, it's created the object of target Type, set with the same Essence properties.
  22. 22. Essence Pattern
  23. 23. Essence Pattern public class Server { public Server(ServerEssence essence) { ... } ... } public class ServerEssence { public void setHost(String host) { ... } public String getHost() { ... } public void setPort(int port) { ... } public int getPort() { ... } // other methods public Server getServer() { if (isValid()) return new Server(this); throw new InvalidServerConfigurationException(this); } ... }

×