Are serializers the right spot to remove shared state from Akka messages? - serialization

I am working on a distributed algorithm and decided to use a Akka to scale it across machines. The machines need to exchange messages very frequently and these messages reference some immutable objects that exist on every machine. Hence, it seems sensible to "compress" the messages in the sense that the shared, replicated objects should not be serialized in the messages. Not only would this save on network bandwidth but it also would avoid creating duplicate objects in the receiver side whenever a message is deserialized.
Now, my question is how to do this properly. So far, I could think of two options:
Handle this on the "business layer", i.e., converting my original message objects to some reference objects that replace references to the shared, replicated objects by some symbolic references. Then, I would send those reference objects rather than the original messages. Think of it as replacing some actual web resource with a URL. Doing this seems rather straight-forward in terms of coding but it also drags serialization concerns into the actual business logic.
Write custom serializers that are aware of the shared, replicated objects. In my case, it would be okay that this solution would introduce the replicated, shared objects as global state to the actor systems via the serializers. However, the Akka documentation does not describe how to programmatically add custom serializers, which would be necessary to weave in the shared objects with the serializer. Also, I could imagine that there are a couple of reasons, why such a solution would be discouraged. So, I am asking here.
Thanks a lot!

It's possible to write your own, custom serializers and let them do all sorts of weird things, then you can bind them at the config level as usual:
class MyOwnSerializer extends Serializer {
// If you need logging here, introduce a constructor that takes an ExtendedActorSystem.
// class MyOwnSerializer(actorSystem: ExtendedActorSystem) extends Serializer
// Get a logger using:
// private val logger = Logging(actorSystem, this)
// This is whether "fromBinary" requires a "clazz" or not
def includeManifest: Boolean = true
// Pick a unique identifier for your Serializer,
// you've got a couple of billions to choose from,
// 0 - 40 is reserved by Akka itself
def identifier = 1234567
// "toBinary" serializes the given object to an Array of Bytes
def toBinary(obj: AnyRef): Array[Byte] = {
// Put the code that serializes the object here
//#...
Array[Byte]()
//#...
}
// "fromBinary" deserializes the given array,
// using the type hint (if any, see "includeManifest" above)
def fromBinary(
bytes: Array[Byte],
clazz: Option[Class[_]]): AnyRef = {
// Put your code that deserializes here
//#...
null
//#...
}
}
But this raises an important question: if your messages all references data that is shared on the machines already, why would you want to put in the message the pointer to the object (very bad! messages should be immutable, and a pointer isn't!), rather than some sort of immutable, string objectId (kinda your option 1) ? This is a much better option when it comes to preserving the immutability of the messages, and there is little change in your business logic (just put a wrapper over the shared state storage)
for more info, see the documentation

I finally went with the solution proposed by Diego and want to share some more details on my reasoning and solution.
First of all, I am also in favor of option 1 (handling the "compaction" of messages in the business layer) for those reasons:
Serializers are global to the actor system. Making them stateful is actually a most severe violation of Akka's very philosophy as it goes against the encapsulation of behavior and state in actors.
Serializers have to be created upfront, anyway (even when adding them "programatically").
Design-wise, one can argue that "message compaction is not a responsibility of the serializer, either. In a strict sense, serialization is merely the transformation of runtime-specific data into a compact, exchangable representation. Changing what to serialize, is not a task of a serializer, though.
Having settled upon this, I still strived for a clear separation of "message compaction" and the actual business logic in the actors. I came up with a neat way to do this in Scala, which I want to share here. The basic idea is to make the message itself look like a normal case class but still allow these messages to "compactify" themselves. Here is an abstract example:
class Sender extends ActorRef {
def context: SharedContext = ... // This is the shared data present on every node.
// ...
def someBusinessLogic(receiver: ActorRef) {
val someData = computeData
receiver ! MyMessage(someData)
}
}
class Receiver extends ActorRef {
implicit def context: SharedContext = ... // This is the shared data present on every node.
def receiver = {
case MyMessage(someData) =>
// ...
}
}
object Receiver {
object MyMessage {
def apply(someData: SomeData) = MyCompactMessage(someData: SomeData)
def unapply(myCompactMessage: MyCompactMessage)(implicit context: SharedContext)
: Option[SomeData] =
Some(myCompactMessage.someData(context))
}
}
As you can see, the sender and receiver code feels just like using a case class and in fact, MyMessage could be a case class.
However, by implementing apply and unapply manually, one can insert its own "compactification" logic and also implicitly inject the shared data necessary to do the "uncompactification", without touching the sender and receiver. For defining MyCompactMessage, I found Protocol Buffers to be especially suited, as it is already a dependency of Akka and efficient in terms of space and computation, but any other solution would do.

Related

Design pattern to ensure that a method A is called before method B

I have a sample(incomplete) class like
class ABC{
public:
void login();
void query_users();
//other methods
private:
//member data
}
This class should be used in a way that login needs to be called first and then only other methods like query_users, etc., can be called. Login sets some private member data for the other methods to use. Is there any simpler way to achieve this other than calling a function that checks if the member data is set at the start of every other method in the class?
There are two general approach I know of, and they differ a good bit. You'll have to pick the appropriate mechanism for the task - in standard class-based OO languages (e.g. Java/C++/C#/Python), they are the only two approaches I know of. (There may be other approaches in different paradigms that I am unfamiliar with.)
1. Check the state.
This is done in many classes already that have to track the state of the system/backing resource. Two common examples are (file) stream and database connections.
A "template" might look like:
void Logon(credentials) { ..; loggedOn = true }
void DieUnlessLoggedIn { if (!loggedOn) { throw .. } }
void DoStuff () { DieUnlessLoggedIn(); .. }
While the above approach is pretty generic, some languages may support invariants (Eiffel), decorations (Python), annotations, AOP, or other assertion mechanisms.
This approach is useful for dynamic state in a mutable world: e.g. what happens after "Logout"? The state for DoStuff is invalid again until a re-logon (if it's allowed). However, this approach cannot be used for compile-time checks in general in mainstream OOP languages because the run-time state simply is not available at compile-time.
2. Use multiple types to represent state.
Create two separate types, such that type ServiceLogon (method Logon) creates ServiceAccess (method DoStuff). Thus DoStuff can only be called (on type ServiceAccess) after created from Logon (on ServiceLogon). This works well to enforce calling order semantics in static languages with member hiding - because programs won't compile if it's wrong.
login = new ServiceLogon(credentials)
access = login.Logon();
access.DoStuff(); // can't be called before obtained via Logon
Using the type to encode additional state can be overly complex as it can fracture a class-based type system, but is useful in "builder" and "repository" patterns and such; basically, ask if the type warrants being split to maintain SRP, then considering this approach.
This approach cannot handle things like "logout" entirely without incorporating state checking as type ServiceAccess would (in the clean sense) always represent the same state due to it being encoded in the type.
1. & 2. Use state checking and state/role-specific types.
A hybrid is totally acceptable, of course, and the above two approaches are not mutually exclusive. It may make sense to separate the roles making one type (and thus methods invoked upon it) dependent upon another method while still checking runtime state as appropriate. As per above, #1 is really good for runtime guards (which can be highly dynamic) while #2 can enforce certain rules at compile-time.
What you can do is to create instances of ABC form a static factory method that returns the instance you can use. In pseudo-code:
abc = ABC.login(); //sets all the state
users = abc.query_users();
I am not sure this is the best way but you can make login() private and call it as part of the constructor, which would ensure that login() is called at time of object creation itself and after that only any other functions can be called (unless you have static functions)
class ABC{
public ABC(credentials){
login(credentails);
}
public:
void query_users();
//other methods
private:
void login();
//member data
}
It will already work first when it goes from the top down. If you want to make sure that login is successful then call the other methods from inside the login() method.
like:
public void login(){
//do login code
if(//code for login check){
//run other methods
}
else{
login(); //re-run login workings
}
}
If you really want to follow good patterns you might try making as many of your classes immutable as possible.
This would imply that your constructor sets the total state (does the entire login) and then the order of the method calls is totally irrelevant.

Is protobuf-net suited for serializing arbitrary object/domain models?

I have been exploring the CQRS/DDD-principles and patterns for a while now and have started implementing a sample project where I have split my storage-model into a WriteModel and a ReadModel. The WriteModel will use a simple NoSQL-like database where aggregates are stored in a key-value style, with value being just a serialized version of the aggregate.
I am now looking at ProtoBuf-Net for serializing and deserializing my domain model aggregates in and out of storage. Other than this post I haven't found any guidance or tips for using ProtoBuf-Net in this area. The point is that the (ideal) requirements for serialization and deserialization of aggregates is that the domain model should have as little knowledge as possible about this infrastructural concern, which implies the following:
No attributes on the classes
No constructors, getters, setters or any other piece of code just for the sake of serialization.
Ability to use any (custom) type possible and have it serialized/deserialized.
Thus far I have implemented just the serialization of the first versions of my aggregates which works perfectly fine. I use the RuntimeTypeModel.Default-instance to configure the MetaModel at runtime and have UseConstructor = false everywhere, which enables me to completely separate the serialization mechanics from my domain-assembly. I have even implemented a custom post-deserialization mechanism that enables me to just-in-time initialize fields after ProtoBuf-Net has deserialized it into a valid instance. So suppose I have class AggregateA like so:
[Version(1)]
public sealed class AggregateA
{
private readonly int _x;
private readonly string _y;
...
}
Then in my serialization-library I have code something along the following lines:
var metaType = RuntimeTypeModel.Default.Add(typeof(AggregateA), false);
metaType.UseConstructor = false;
metaType.AddField(1, "_x");
metaType.AddField(2, "_y");
...
However, I realize that up to this point I have only implemented the basic scenario, and I am now starting to think about how to approach versioning of my model. I am particularly interested in larger refactoring-scenario's, where type A has been split into type A1 and A2, for example:
[Version(2)]
public sealed class AggregateA1
{
private readonly int _x;
...
}
[Version(2)]
public sealed class AggregateA2
{
private readonly string _y;
...
}
Suppose I have a serialized bunch of instances of AggregateA, but now my domain model knows only AggregateA1 and AggregateA2, how would you handle this scenario with ProtoBuf-Net?
A second question deals with point 3: is ProtoBuf-Net capable of handling arbitrary types if you're willing to put in some extra configuration-effort? I've read about exceptions raised when using the DateTimeOffset-type, which makes me think not all types can be serialized by the framework out-of-the-box, but can I serialize these types by registering them in the RuntimeTypeModel? Should I even want to go there? Or better to forget about serializing common .NET types other than the simple ones?
protobuf-net is intended to work with predictable known models. It is true that everything can be configured at runtime, but I have not put any thought as to how to handle your A1/A2 scenario, precisely because that is not a supported scenario (in my defense, I can't see that working nicely with most serializers). Thinking off the top of my head, if you have the configuration/mapping data somewhere, then you could simply deserialize twice; i.e. as long as we still tell it that AggregateA1._x maps to 1 and AggregateA2._y maps to 2, you can do:
object a1 = model.Deserialize(source, null, typeof(AggregateA1));
source.Position = 0; // rewind
object a2 = model.Deserialize(source, null, typeof(AggregateA2));
However, more complex tweaks would require additional thought.
Re "arbitrary types"... define "arbitrary" ;p In particular, there is support for "surrogate" types which can be useful for some transformations - but without a very specific "problem statement" it is hard to answer completely.
Summary:
protobuf-net has an intended usage, which includes both serialization-aware (attributed, etc) and non-aware scenarios (runtime configuration, etc) - but it also works for a range of more bespoke scenarios (letting you drop to the raw reader/writer API if you want to). It does not and cannot guarantee to be a direct fit for every serialization scenario imaginable, and how well it behaves will depend on how far from that scenario you are.

Protocol buffer and OO design

I'm using protocol buffer as a wire data-format in a client-server architecture. Domain objects (java beans) will go through following life-cycle.
Used in client side business logic
Converted to protobuf format
Transmitted to the server
Converted back to domain object
Used in server side business logic
"Protocol Buffers and O-O Design" section in ProtoBuf documentation recommends wrapping generated class inside proper domain model.
I'd like to find-out the best appoach.
For e.g. I have a simple proto definition.
package customer;
option java_package = "com.example";
option java_outer_classname = "CustomerProtos";
message Customer {
required string name = 1;
optional string address = 2;
}
This is how domain model is defined. As you can see, the data is completely stored in proto builder object.
package com.example;
public class CustomerModel
{
private CustomerProtos.Customer.Builder builder = CustomerProtos.Customer.newBuilder();
public String getName()
{
return builder.getName();
}
public void setName(String name)
{
builder.setName(name);
}
public String getAddress()
{
return builder.getAddress();
}
public void setAddress(String address)
{
builder.setAddress(address);
}
public byte[] serialize()
{
return builder.build().toByteArray();
}
}
Is this a good practice? because these objects are used in all phases of life-cycle, but we only requires protocolbuf format at client-server transmission phase.
Is there any performance issue when accessing proto builder class getter/setter methods specially when proto definition is complex and nested?
I have no experience with protocol buffers, but I would not recommend implementing your domain objects tailored to a specific serialization/transfer framework. You might regret that in the future.
The domain objects and logic of a software application should be as independent as possible from specific implementation issues (in your case serialization/transfer), because you want your domain to be easy to understand and be reusable/maintainable in the future.
If you want to define your domain objects independent of serialization/transfer, you have two options:
Before serialization/transfer, you copy the information to protocol
buffers specific objects and send them to your server. There you
would have to copy the information back to your domain objects.
Use a non-protocol serialization library like Kryo or
ProtoStuff to directly transfer your domain objects to the
server.
The disadvantages of option 1 are that your domain is defined two times (which is undesirable with respect to modifications) and the copying of information (which produces error-prone and non maintainable code).
The disadvantages of option 2 are that you lose schema evolution (although ProtoStuff apparently supports it) and the complete (potentially large) object graph is serialized and transferred. Although you could prune the object graph (manually or with JGT) before serialization/transfer.
We've made a protobuf-converter to solve the problem of transformation of your Domain Model Objects into Google Protobuf Messages and vice versa.
How to use it:
Domain model classes that have to be transformed into protobuf messages must satisfy conditions:
Class has to be marked by #ProtoClass annotaion that contains
reference on related protobuf message class.
Class fields has to be marked by #ProtoField annotaion. These fields must have getters and setters.
E.g.:
#ProtoClass(ProtobufUser.class)
public class User {
#ProtoField
private String name;
#ProtoField
private String password;
// getters and setters for 'name' and 'password' fields
...
}
Code for conversion User instance into related protobuf message:
User userDomain = new User();
...
ProtobufUser userProto = Converter.create().toProtobuf(ProtobufUser.class, userDomain);
Code for backward conversion:
User userDomain = Converter.create().toDomain(User.class, userProto);
Conversion of lists of objects is similar to single object conversion.

Mediator Vs Observer Object-Oriented Design Patterns

I have been reading the Gang Of Four, in order to solve some of my problems and came across the Mediator pattern.
I had earlier used Observer in my projects for making some GUI application. I am a bit confused as I do not find great difference between the two. I browsed to find the difference but could not find any apt answer for my query.
Could some one help me to differentiate between the two with some good example which clearly demarcates the two?
The Observer pattern:
Defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
The Mediator pattern:
Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
Source: dofactory
Example:
The observer pattern:
Class A, can have zero or more observers of type O registered with it. When something in A is changed it notifies all of the observers.
The mediator pattern:
You have some number of instances of class X (or maybe even several different types:X, Y & Z), and they wish to communicate with each other (but you don't want each to have explicit references to each other), so you create a mediator class M. Each instance of X has a reference to a shared instance of M, through which it can communicate with the other instances of X (or X, Y and Z).
In the original book that coined the terms Observer and Mediator, Design Patterns, Elements of Reusable Object-Oriented Software, it says that the Mediator pattern can be implemented by using the observer pattern. However it can also be implemented by having Colleagues (which are roughly equivalent to the Subjects of the Observer pattern) have a reference to either a Mediator class or a Mediator interface.
There are many cases when you would want to use the observer pattern, they key is that an object should not know what other objects are observing it's state.
Mediator is a little more specific, it avoids having classes communicate directly but instead through a mediator. This helps the Single Responsibility principle by allowing communication to be offloaded to a class that just handles communication.
A classic Mediator example is in a GUI, where the naive approach might lead to code on a button click event saying "if the Foo panel is disabled and Bar panel has a label saying "Please enter date" then don't call the server, otherwise go ahead", where with the Mediator pattern it could say "I'm just a button and have no earthly business knowing about the Foo panel and the label on the Bar panel, so I'll just ask my mediator if calling the server is O.K. right now."
Or, if Mediator is implemented using the Observer pattern the button would say "Hey, observers (which would include the mediator), my state changed (someone clicked me). Do something about it if you care". In my example that probably makes less sense then directly referencing the mediator, but in many cases using the Observer pattern to implement Mediator would make sense, and the difference between Observer and Mediator would be more one of intent than a difference in the code itself.
Observer
1. Without
Client1: Hey Subject, when do you change?
Client2: When did you change Subject? I have not noticed!
Client3: I know that Subject has changed.
2. With
Clients are silent.
Some time later ...
Subject: Dear clients, I have changed!
Mediator
1. Without
Client1: Hey Taxi1, take me some where.
Client2: Hey Taxi1, take me some where.
Client1: Hey Taxi2, take me some where.
Client2: Hey Taxi2, take me some where.
2. With
Client1: Hey TaxiCenter, please take me a Taxi.
Client2: Hey TaxiCenter, please take me a Taxi.
These patterns are used in different situations:
The mediator pattern is used when you have two sub-systems with some dependency and one of them is due for a change, and since you might not want to change the system that depends on the other, you may want to introduce a mediator which will decouple the dependency between them. That way, when one of the sub-systems changes, all you have to do is to update the mediator.
The observer pattern is used when a class wants to allow other classes to register themselves and receive notifications upon events, e. g. ButtonListener etc.
Both of these patterns allow for lesser coupling, but are quite different.
Lets go by an example: consider you want to build two application:
Chat application.
Emergency ambulance operator application.
mediator
Building the chat application you will be choosing the mediator design pattern.
The persons may be joining and leaving the chat at any given time, so it does not make any sense to keep direct reference between two persons chatting.
We still need to facilitate a communication between two persons and allow them have a chat.
Why will we prefer the mediator? just have a look at its definition:
With the mediator pattern, communication between objects is
encapsulated within a mediator object. Objects no longer communicate
directly with each other, but instead communicate through the
mediator. This reduces the dependencies between communicating objects,
thereby reducing coupling.
How is the magic works? First we will create the chat mediator and make the persons objects register to it, so it will have two directional connection with every single person (the person can send message using the chat mediator cause it ha access to it, and the chat mediator will access the received method of the person object cause he also has access to it)
function Person(name) {
let self = this;
this._name = name;
this._chat = null;
this._receive(from, message) {
console.log("{0}: '{1}'".format(from.name(), message));
}
this._send(to, message) {
this._chat.message(this, to, message);
}
return {
receive: (from, message) => { self._receive(from, message) },
send: (to, message) => { self._send(to, message) },
initChat: (chat) => { this._chat = chat; },
name: () => { return this._name; }
}
}
function ChatMediator() {
let self = this;
this._persons = [];
return {
message: function (from, to, message) {
if (self._persons.indexOf(to) > -1) {
self._persons[to].receive(from, message);
}
},
register: function (person) {
person.initChat(self);
self._persons.push(person);
}
unRegister: function (person) {
person.initChat(null);
delete self._persons[person.name()];
}
}
};
//Usage:
let chat = new ChatMediator();
let colton = new Person('Colton');
let ronan = new Person('Ronan');
chat.register(colton);
chat.register(ronan);
colton.send(ronan, 'Hello there, nice to meet you');
ronan.send(colton, 'Nice to meet you to');
colton.send(ronan, 'Goodbye!');
chat.unRegister(colton);
observer
Building the 911 call application you will be choosing the observer design pattern.
Each ambulance observer object wishes to be informed when there is an emergency state, so he can drive the address and give help.
The emergency operator observable keep reference to each on of the ambulance observers and notify them when help is needed (or generating event).
Why will we prefer the observer? just have a look at its definition:
An object, called the subject, maintains a list of its dependents,
called observers, and notifies them automatically of any state
changes, usually by calling one of their methods.
function AmbulanceObserver(name) {
let self = this;
this._name = name;
this._send(address) {
console.log(this._name + ' has been sent to the address: ' + address);
}
return {
send: (address) => { self._send(address) },
name: () => { return this._name; }
}
}
function OperatorObservable() {
let self = this;
this._ambulances = [];
return {
send: function (ambulance, address) {
if (self._ambulances.indexOf(ambulance) > -1) {
self._ambulances[ambulance].send(address);
}
},
register: function (ambulance) {
self._ambulances.push(ambulance);
}
unRegister: function (ambulance) {
delete self._ambulances[ambulance.name()];
}
}
};
//Usage:
let operator = new OperatorObservable();
let amb111 = new AmbulanceObserver('111');
let amb112 = new AmbulanceObserver('112');
operator.register(amb111);
operator.register(amb112);
operator.send(amb111, '27010 La Sierra Lane Austin, MN 000');
operator.unRegister(amb111);
operator.send(amb112, '97011 La Sierra Lane Austin, BN 111');
operator.unRegister(amb112);
The Differences:
The chat mediator has two way communication between the persons objects (send and receive) wheres the operator observable has only one way communication (It tell the ambulance observer to drive and finish).
The chat mediator can make the persons objects interact between them (even if it not a direct communication), the ambulances observers only registers to the operator observable events.
Each person object has a reference to the chat mediator, and also the chat mediator keep reference to the every one of the persons. Wheres the ambulance observer does not keep reference to the operator observable, only the operator observable keep reference to every ambulance observer.
Although both of them are used for organised way of telling about state changes, they're slightly different structurally and semantically IMO.
Observer is used to broadcast a state change of a particular object, from the object itself. So the change happens in the central object that is also responsible for signalling it. However, in Mediator, state change can happen in any object but it's broadcasted from a mediator. So there's a difference in the flow. But, I don't think this affects our code behaviour. We can use one or another to achieve the same behaviour. On the other hand, this difference might have some affects on conceptual understanding of the code.
See, the primary purpose of using patterns is rather to create a common language between developers. So, when I see a mediator, I personally understand multiple elements trying to communicate over a single broker/hub to reduce communication noise (or to promote SRP) and each object is equally important in terms of having the ability of signalling a state change. For example, think of multiple aircrafts approaching to an airport. Each should communicate over the pylon (mediator) rather than communicating with each other. (Think of 1000 aircrafts communicating with each other when landing - that would be a mess)
However, when I see an observer, it means there're some state changes I might be care about and should register/subscribe to listen particular state changes. There's a central object responsible for signalling state changes. For example, if I care about a specific airport on my way from A to B, I can register to that airport to catch some events broadcasted like if there's an empty runway or something like that.
Hope it's clear.
#cdc explained the difference in intent excellently.
I will add some more info on top it.
Observer : Enables notification of a event in one object to different set of objects ( instances of different classes)
Mediator: Centralize the communication between set of objects, created from a particular class.
Structure of Mediator pattern from dofactory:
Mediator: Defines an interface for communication between Colleagues.
Colleague: Is an abstract class, which defines the events to be communicated between Colleagues
ConcreteMediator: Implements cooperative behavior by coordinating Colleague objects and maintains its colleagues
ConcreteColleague: Implements the notification operations received through Mediator, which has been generated by other Colleague
One real world example:
You are maintaining a network of computers in Mesh topology. If a new computer is added Or existing computer is removed, all other computers in that network should know about these two events.
Let's see how Mediator pattern fits into it.
Code snippet:
import java.util.List;
import java.util.ArrayList;
/* Define the contract for communication between Colleagues.
Implementation is left to ConcreteMediator */
interface Mediator{
public void register(Colleague colleague);
public void unregister(Colleague colleague);
}
/* Define the contract for notification events from Mediator.
Implementation is left to ConcreteColleague
*/
abstract class Colleague{
private Mediator mediator;
private String name;
public Colleague(Mediator mediator,String name){
this.mediator = mediator;
this.name = name;
}
public String toString(){
return name;
}
public abstract void receiveRegisterNotification(Colleague colleague);
public abstract void receiveUnRegisterNotification(Colleague colleague);
}
/* Process notification event raised by other Colleague through Mediator.
*/
class ComputerColleague extends Colleague {
private Mediator mediator;
public ComputerColleague(Mediator mediator,String name){
super(mediator,name);
}
public void receiveRegisterNotification(Colleague colleague){
System.out.println("New Computer register event with name:"+colleague+
": received #"+this);
// Send further messages to this new Colleague from now onwards
}
public void receiveUnRegisterNotification(Colleague colleague){
System.out.println("Computer left unregister event with name:"+colleague+
":received #"+this);
// Do not send further messages to this Colleague from now onwards
}
}
/* Act as a central hub for communication between different Colleagues.
Notifies all Concrete Colleagues on occurrence of an event
*/
class NetworkMediator implements Mediator{
List<Colleague> colleagues = new ArrayList<Colleague>();
public NetworkMediator(){
}
public void register(Colleague colleague){
colleagues.add(colleague);
for (Colleague other : colleagues){
if ( other != colleague){
other.receiveRegisterNotification(colleague);
}
}
}
public void unregister(Colleague colleague){
colleagues.remove(colleague);
for (Colleague other : colleagues){
other.receiveUnRegisterNotification(colleague);
}
}
}
public class MediatorPatternDemo{
public static void main(String args[]){
Mediator mediator = new NetworkMediator();
ComputerColleague colleague1 = new ComputerColleague(mediator,"Eagle");
ComputerColleague colleague2 = new ComputerColleague(mediator,"Ostrich");
ComputerColleague colleague3 = new ComputerColleague(mediator,"Penguin");
mediator.register(colleague1);
mediator.register(colleague2);
mediator.register(colleague3);
mediator.unregister(colleague1);
}
}
output:
New Computer register event with name:Ostrich: received #Eagle
New Computer register event with name:Penguin: received #Eagle
New Computer register event with name:Penguin: received #Ostrich
Computer left unregister event with name:Eagle:received #Ostrich
Computer left unregister event with name:Eagle:received #Penguin
Explanation:
Eagle is added to network at first through register event. No notifications to any other colleagues since Eagle is the first one.
When Ostrich is added to the network, Eagle is notified : Line 1 of output is rendered now.
When Penguin is added to network, both Eagle and Ostrich have been notified : Line 2 and Line 3 of output is rendered now.
When Eagle left the network through unregister event, both Ostrich and Penguin have been notified. Line 4 and Line 5 of output is rendered now.
How About this explanation
Technically both Observer and Mediator are the same and are used to provide decoupled way for component communication, but usage is different.
While obeserver notifies subscribed components about state changes (creation of new db record, for instance), the mediator commands registered components to do something related to business logic flow (sending email to user for password reset).
Observer
Notification consumers are responsible to subscribe in order to receive notifications
Notification processing is not part of business flow
Mediator
Explicit registration required to connect "publisher" and "consumers"
Notification processing is part of specific business flow

God object - decrease coupling to a 'master' object

I have an object called Parameters that gets tossed from method to method down and up the call tree, across package boundaries. It has about fifty state variables. Each method might use one or two variables to control its output.
I think this is a bad idea, beacuse I can't easily see what a method needs to function, or even what might happen if with a certain combination of parameters for module Y which is totally unrelated to my current module.
What are some good techniques for decreasing coupling to this god object, or ideally eliminating it ?
public void ExporterExcelParFonds(ParametresExecution parametres)
{
ApplicationExcel appExcel = null;
LogTool.Instance.ExceptionSoulevee = false;
bool inclureReferences = parametres.inclureReferences;
bool inclureBornes = parametres.inclureBornes;
DateTime dateDebut = parametres.date;
DateTime dateFin = parametres.dateFin;
try
{
LogTool.Instance.AfficherMessage(Variables.msg_GenerationRapportPortefeuilleReference);
bool fichiersPreparesAvecSucces = PreparerFichiers(parametres, Sections.exportExcelParFonds);
if (!fichiersPreparesAvecSucces)
{
parametres.afficherRapportApresGeneration = false;
LogTool.Instance.ExceptionSoulevee = true;
}
else
{
The caller would do :
PortefeuillesReference pr = new PortefeuillesReference();
pr.ExporterExcelParFonds(parametres);
First, at the risk of stating the obvious: pass the parameters which are used by the methods, rather than the god object.
This, however, might lead to some methods needing huge amounts of parameters because they call other methods, which call other methods in turn, etcetera. That was probably the inspiration for putting everything in a god object. I'll give a simplified example of such a method with too many parameters; you'll have to imagine that "too many" == 3 here :-)
public void PrintFilteredReport(
Data data, FilterCriteria criteria, ReportFormat format)
{
var filteredData = Filter(data, criteria);
PrintReport(filteredData, format);
}
So the question is, how can we reduce the amount of parameters without resorting to a god object? The answer is to get rid of procedural programming and make good use of object oriented design. Objects can use each other without needing to know the parameters that were used to initialize their collaborators:
// dataFilter service object only needs to know the criteria
var dataFilter = new DataFilter(criteria);
// report printer service object only needs to know the format
var reportPrinter = new ReportPrinter(format);
// filteredReportPrinter service object is initialized with a
// dataFilter and a reportPrinter service, but it doesn't need
// to know which parameters those are using to do their job
var filteredReportPrinter = new FilteredReportPrinter(dataFilter, reportPrinter);
Now the FilteredReportPrinter.Print method can be implemented with only one parameter:
public void Print(data)
{
var filteredData = this.dataFilter.Filter(data);
this.reportPrinter.Print(filteredData);
}
Incidentally, this sort of separation of concerns and dependency injection is good for more than just eliminating parameters. If you access collaborator objects through interfaces, then that makes your class
very flexible: you can set up FilteredReportPrinter with any filter/printer implementation you can imagine
very testable: you can pass in mock collaborators with canned responses and verify that they were used correctly in a unit test
If all your methods are using the same Parameters class then maybe it should be a member variable of a class with the relevant methods in it, then you can pass Parameters into the constructor of this class, assign it to a member variable and all your methods can use it with having to pass it as a parameter.
A good way to start refactoring this god class is by splitting it up into smaller pieces. Find groups of properties that are related and break them out into their own class.
You can then revisit the methods that depend on Parameters and see if you can replace it with one of the smaller classes you created.
Hard to give a good solution without some code samples and real world situations.
It sounds like you are not applying object-oriented (OO) principles in your design. Since you mention the word "object" I presume you are working within some sort of OO paradigm. I recommend you convert your "call tree" into objects that model the problem you are solving. A "god object" is definitely something to avoid. I think you may be missing something fundamental... If you post some code examples I may be able to answer in more detail.
Query each client for their required parameters and inject them?
Example: each "object" that requires "parameters" is a "Client". Each "Client" exposes an interface through which a "Configuration Agent" queries the Client for its required parameters. The Configuration Agent then "injects" the parameters (and only those required by a Client).
For the parameters that dictate behavior, one can instantiate an object that exhibits the configured behavior. Then client classes simply use the instantiated object - neither the client nor the service have to know what the value of the parameter is. For instance for a parameter that tells where to read data from, have the FlatFileReader, XMLFileReader and DatabaseReader all inherit the same base class (or implement the same interface). Instantiate one of them base on the value of the parameter, then clients of the reader class just ask for data to the instantiated reader object without knowing if the data come from a file or from the DB.
To start you can break your big ParametresExecution class into several classes, one per package, which only hold the parameters for the package.
Another direction could be to pass the ParametresExecution object at construction time. You won't have to pass it around at every function call.
(I am assuming this is within a Java or .NET environment) Convert the class into a singleton. Add a static method called "getInstance()" or something similar to call to get the name-value bundle (and stop "tramping" it around -- see Ch. 10 of "Code Complete" book).
Now the hard part. Presumably, this is within a web app or some other non batch/single-thread environment. So, to get access to the right instance when the object is not really a true singleton, you have to hide selection logic inside of the static accessor.
In java, you can set up a "thread local" reference, and initialize it when each request or sub-task starts. Then, code the accessor in terms of that thread-local. I don't know if something analogous exists in .NET, but you can always fake it with a Dictionary (Hash, Map) which uses the current thread instance as the key.
It's a start... (there's always decomposition of the blob itself, but I built a framework that has a very similar semi-global value-store within it)