Architecture is a design pattern meeting a certain set of requirements under a given set of constraints minimizing the risk. One must know the requirements (non-functional), constraints and risk to design the architect. Its mostly based on non-functional requirements. It covers the whole system.
Design Patterns are actually detailed design patterns. They go into the coding level. Its about functional requirements. Its about implementing a given requirement.
Functional Requirements ----> OO Design -------> Code
Implementation
Thus there are
two types of design -
1. Architecture Design
2. Detailed Design
Designs/Design
Patterns are dependent on language and platform. Design to a problem would be
different in Java and .Net.
Ex: Session Management is different in Java .Net.
Types of Design Patterns
The authors of the
original Design Pattern book divided the 23 patterns into three categories
based on what actually the patterns do in a design solution. These categories
are:-
● Creational -
Design patterns belonging to these category are used for creating objects.
Using such a design pattern provides more flexibility where we require a
control over the creation of objects. One very common use case is the usage of
a creational design pattern to restrict the total number of instances of a
class.
● Structural -
This category groups all those design patterns which help the user to group
objects into larger structures to meet the complex requirements in a structured
way. A common use case is to use such a design pattern for designing a complex
user interface.
● Behavioral -
Patterns belonging to this category are used to define communication between
objects of a proposed solution. In other words such design patterns helps
defining the flow of a complex system.
For ex: Chain of
Responsibility Pattern, Strategy Pattern, Iterator Pattern, etc.
How to show a design
1. Static Diagrams:
2. Dynamic Diagrams:
NOTE: Inheritance (is a relationship) can be converted into/modeled
as composition (has a relationship), but not vice-versa.
Polymorphism
Polymorphism refers to
the ability of an object to behave differently to the same message. It is of
two types. static or dynamic.
Dynamic
polymorphism: Response to message is decided on run-time. It is implemented by overriding. The
assignment of data types in dynamic polymorphism is known as late or dynamic
binding. In dynamic binding method call occur based on the object (instance)
type at Run time.
Static
polymorphism: Response to message is decided on compile-time. It is implemented by overloading. If
the assignment of data types is in compile time, it is known as early or static
binding. In static binding, method call occur based on the reference type
at compile time.
Dynamic Polymorphism
Single Dispatching:
Decision is based on a single object.
Dual Dispatching: Decision
is based on two objects.
Mutiple
Dispatching: Decision is based on multiple objects.
Dynamic Polymorphism Vs Reflection
Dynamic
polymorphism use single lookup (for single dispatching, no support for
dual/multiple dispatching in Java), whereas Reflection uses 6-7 lookups.
Thus dynamic polymorphism works much better than reflection.
Design Rules
OCP Rule (Open Closed Principle): Open to extension
but close to change. We are not afraid of change, but testing. Testing costs a
lot and adds more in big projects. Adding something new shouldn't break
anything existing.
SRP (Single Responsibility Principle) / High Cohension:
A class with less responsibilities is highly cohesive and a class with more
responsibilities is less cohesive.
DIP (Dependency Inversion Principle): As per
DIP, dependencies are inverted i.e. derived class depends on base class. When
base class knows about derived, DIP is broken.
In OO, knowledge
framework is bottom up i.e derived classes knowing about base classes whereas
in procedural programming, knowledge is top down i.e base class having
knowledge of derived class.
Notes:
1. Save OCP -> Use
polymorphism.
2. Remove High
coupling -> Use interfaces
Design Patterns:
1. Factory
Pattern
2. Abstract
Factory Pattern
3. Factory
Method Design Pattern: A class that creates objects as well as has some business logic. Above two just creates
objects.
4. Template Design Pattern
5. Strategy Design Pattern
6. Command
design pattern
7. Chain
of responsibility ( Used only when business rules exist)
8. Lookup
pattern (used in multiple dispatching)
9. Prototype Design pattern
10. Singleton Design
Pattern
11. Decorator/Pipe
Filter Design Pattern:
12. Adapter Design
Pattern
13. Proxy Design
Pattern
14. Bridge Design
Pattern
15. Visitor Design
Pattern
16. Creator Design
Pattern
17. Builder
Design Pattern
18. Dependency
Injection
19. Object Pool Design
Pattern/ Resource Pool Manager
20. Flyweight Design
Pattern
21. Mediator Design
Pattern
22. Facade Design
Pattern
23. Observer Design
Pattern
24. Interface Design
Pattern
25. State Pattern
Template Design Pattern: It maintains is-a relationship. It
binds things at compile time. Ex: exploited by
Struts RequestProcessor class’s process() method
Strategy Design Pattern: Solves the same problem as template
design pattern, except that it maintains has-a relationship. It binds things at
run time. Vary the logic independent of family.
Ex: An invoice may
have many things like Tax, etc and a method to calculate Tax,
calculateTax(). Now there could be different types of Tax. Though
calculateTax() depends on Tax family, but remember that it can depend with
other factors as well. so, we keep both of them separate.
Decorator/Pipe Filter Design Pattern: Used for enrichment at run
time. If you don't know aggregation at compile time, use decorators. It's being
said that order doesn't matter, though it matters. Can we format the
text after encoding it? No, we can't.
A decorator object’s interface must conform to the interface of the component it decorates.
A decorator object’s interface must conform to the interface of the component it decorates.
Composite design pattern: Composite pattern describes that a group of objects are to be treated in the
same way as a single instance of an object. The intent of a composite is to
"compose" objects into tree structures to represent part-whole
hierarchies. Implementing the composite pattern lets clients treat individual
objects and compositions uniformly.
Ex: Manager-Subordinate
relationship. Both manager and subordinate are employees and manager manages a
group of subordinates.
This design pattern is
used to make a composite of several primitive or composite member objects to
have a common class which can accept calls intended to a variety of specialized
objects (or cases). The composite children are normally termed as nodes and the
primitives are called leaves.
Example: Suppose we need
a common method which returns the specialized technical skills of an employee
and all of its reportees, then the Employee class may
have a data structure to store all the reportees which will
themselves be instances of the Employee class only. Now we can have a common
method getExpertise() which will club the skills of the Employee including reportees and return the clubbed data.
Singleton Design Pattern: It should be used very rarely. It
prevents scalability. Like, in a large application, singleton will always
return same object and hence, we need to have a lot of synchronization for the
object. It should never be used to save memory. One should have a strong reason
for using singleton pattern.
Flyweight Design Pattern: Use a factory to get the
object. That factory maintains cache. Whenever a request for an object comes, it gives the object from cache if it exists; and otherwise creates a new
one. This also has synchronization issues similar to singleton pattern, but are
less. Its a singleton pattern w.r.t. state.
Ex: Used by Java
String class
The flyweight pattern
improves application performance through object reuse (which minimizes the
overhead such as memory allocation, garbage collection etc).
Observer Design Pattern: Used for broadcasting. Also known as
publisher-subscriber pattern.
Ex: Various departments
like sales, logistics, taxation want to be notified whenever there is a change
in stock/inventory levels. So, departments act as subscribers/observers and stock
controller acts as publisher.
Interface Design pattern: Decreases coupling.
Abstract Factory Pattern: This design pattern is very
similar to the Factory Pattern with the only difference that it takes the
abstraction to another level higher. This pattern is basically used to return
one of several related classes of objects i.e., one of several Factories (which
in turn return the actual instance based on the passed parameter as explained
above). One common example of this design pattern is to implement user
interfaces. Suppose you're building an UI for three platforms - Windows, Mac,
and Linux. Now you can use Abstract Factory pattern to return each of the
Factories (Windows, Mac, and Linux) which will themselves return one of the
various UI Components based on the passed parameter.
Builder Design Pattern: This is used for building a different set
of objects based on passed parameters. It’s different from Factory pattern in
the sense that Factory pattern returns objects of diff type (all belonging to
same parent class) whereas Builder pattern builds a set of objects and not just
a descendant.
Ex: decorator objects can't be constructed in factory manner, since composition is not fixed. To create such type of objects, you may use builder pattern.
Ex: decorator objects can't be constructed in factory manner, since composition is not fixed. To create such type of objects, you may use builder pattern.
Builder Vs Factory Pattern
Factory pattern can almost be seen as a simplified version of the Builder pattern. In the Factory pattern, the factory is in charge of creating various subtypes of an object depending on the needs. The user of a factory method doesn't need to know the exact subtype of that object.
Ex: An example of a factory method createCar might return a Ford or a Honda typed object.
In the Builder pattern, different subtypes are also created by a builder method, but the composition of the objects might differ within the same subclass. To continue the car example you might have a createCar builder method which creates a Honda-typed object with a 4 cylinder engine, or a Honda-typed object with 6 cylinders. The builder pattern allows for this finer granularity.
Dependency Injection (DI): Replaces factory. Factory
still has coupling in it. To remove the coupling, we use DI. Here, config file takes care of instantiating
the objects.
Ex: Springs.
Inversion of control or dependency injection (which is a specific type of IoC) is a term used to resolve object dependencies by injecting an instantiated object to satisfy dependency as opposed to explicitly requesting an object. So objects will not be explicitly requested but objects are provided as needed with the help of an Inversion Of Controller container (e.g. Spring). Hence it is called inversion of control.
There are three types
of dependency injections.
1. Constructor Injection (e.g. Pico container, Spring etc): Injection is done through constructors.
2. Setter Injection (e.g. Spring): Injection is done through setter methods.
3. Interface Injection (e.g. Avalon): Injection is done through an interface.
1. Constructor Injection (e.g. Pico container, Spring etc): Injection is done through constructors.
2. Setter Injection (e.g. Spring): Injection is done through setter methods.
3. Interface Injection (e.g. Avalon): Injection is done through an interface.
Spring supports both
constructor-based injection and setter-based injection.
Constructor Injection => SpringConfig.xml
<beans>
<bean
id="car" class="CarBO" singleton="false" >
<constructor-arg>
<ref
bean="carDao" />
</constructor-arg>
</bean>
<bean
id="carDao” class="CarDAOImpl" singleton="false" />
</beans>
Now your CarBO code
changes to:
class CarBO
{
{
private CarDAO dao = null;
public CarBO(CarDAO dao)
{
{
this.dao = dao;
}
public
void getCars(String color)
{
{
/ *
if you need to use a different implementation class say FastCarDAOImpl, then need to make one change only to the SpringConfig.xml file to use a different implementation class(i.e. class=”FastCarDAOImpl”) rather than having to change all the callers.
*/
if you need to use a different implementation class say FastCarDAOImpl, then need to make one change only to the SpringConfig.xml file to use a different implementation class(i.e. class=”FastCarDAOImpl”) rather than having to change all the callers.
*/
List listCars =
dao.findCarsByColor(color);
}
}
Your calling code
would be (e.g. from a Web client):
ApplicationContext ctx
= new FileSystemXmlApplicationContext("SpringConfig.xml");
//lookup “car” in your
caller where “carDao” is dependency injected using the constructor.
CarBO bo =
(CarBO)ctx.getBean("car"); //Spring creates an instance of CarBO
object with an instance of
CarDAO object as the constructor arg.
String color = red;
bo.getCars(color)
Setter injection
<beans>
<property
name=”dao”>
<ref
bean="carDao" />
</property>
</bean>
<bean
id="carDao” class="CarDAOImpl" singleton="false" />
</beans>
Now your CarBO code
changes to:
class CarBO
{
{
private CarDAO dao = null;
public CarBO() {}
….
public
void setDao(CarDAO carDao)
{
{
this.dao = carDao;
}
public
void getCars(String color)
{
{
List listCars =
dao.findCarsByColor(color);
}
}
Your caller code would
be (e.g. from a Web client) same as above.
Constructor injection Vs Setter Injection
There is no clear cut
answer for this question. It is a good practice to start with constructor-based injection since it permits
immutability (i.e. if your classes are meant to be immutable)
and also constructors with parameters give you a clear statement of what is
required to create a valid object. If there is more than one way to create a
valid object, then provide multiple constructors. But if you have a lot of
constructor parameters then your constructors can look messy and also if you
have many string based parameters, then setter-based injection will be more
descriptive because each setter name will indicate what the string is supposed
to do (e.g. setFirstName(…), setLastName(…) etc)
Benefits of IoC (aka Dependency Injection)
1. Minimizes
the amount of code in your application. With IoC containers you do not care
about how services are created and how you get references to the ones you need.
You can also easily add additional services by adding a new constructor or a
setter method with little or no extra configuration.
2. Makes
your application more testable by not requiring any singletons or JNDI lookup
mechanisms in your unit test cases. IoC containers make unit testing and
switching implementations very easy by manually allowing you to inject your own
objects into the object under test.
3. Loose
coupling is promoted with minimal effort and least intrusive mechanism. The
factory design pattern is more intrusive because components or services need to
be requested explicitly whereas in IoC the dependency is injected into the
requesting code.
4. IoC
containers support eager instantiation and lazy loading of services. Containers
also provide support for instantiation of managed objects, cyclical
dependencies, life cycle management, and dependency resolution between managed
objects etc.
Model-View-Controller (MVC) design pattern: MVC stands for Model-View-Controller architecture. It divides the functionality of displaying and maintaining of the data to minimize the degree of coupling (i.e. promotes loose coupling) between components. It is often used by applications that need the ability to maintain multiple views like html, wml, XML based Web service etc of the same data. Multiple views and controllers can interface with the same model. Even new types of views and controllers can interface with a model without forcing a change in the model design.
ActionServlet class is the controller part of the MVC
implementation and is the core of the framework. It processes user requests,
determines what the user is trying to achieve according to the request, pulls
data from the model (if necessary) to be given to the appropriate view, and
selects the proper view to respond to the user.
Front controller design pattern: The MVC pattern can be further
improved and simplified by using the Front Controller pattern with command
objects. The Front Controller pattern uses a single servlet, which acts as
initial point of contact for handling all the requests, including invoking
services such as security (authentication and authorization), logging,
gathering user input data from the request, etc by delegating them to the helper
classes, and managing the choice of an appropriate view with the dispatcher
classes. These helper and dispatcher classes are generally instances of a command design pattern and
therefore usually termed as command objects. The Front Controller pattern
improves manageability, and improves re-usability by moving common behavior
among command objects into the centralized controller or controller managed
helper classes.
Command Design Pattern: Uses lookup method. Here exists a
class which uses the lookup technique to decide which method to call actually.
Each class has only one action. This pattern should be last choice to go with.
Ex: Struts controller uses the command design pattern by calling the
Action classes based on the configuration file struts-config.xml
The Command pattern is
an object behavioral pattern that allows you to achieve complete decoupling between the
sender and the receiver. A sender is an object that invokes an operation, and a
receiver is an object that receives the request to execute a certain operation.
With decoupling, the sender has no knowledge of the Receiver's interface. The
term request here refers to the command that is to be executed. The Command
pattern also allows you to vary
when and how a request is fulfilled. At times it is necessary to issue requests
to objects without knowing anything about the operation being requested or the
receiver of the request. In procedural languages, this type of communication is
accomplished via a call-back - a function that is registered somewhere to be
called at a later point. Commands are the object-oriented equivalent of
call-backs and encapsulate the call-back function.
Ex: Calculator uses command design pattern. Execute method decides
via command interface which operation like +, -, *, % it should execute.
Chain
of Responsibility Design Pattern: In OO Design, the
chain-of-responsibility pattern is a design pattern
consisting of a source of command objects
and a series of processing objects. Each processing object contains a set of
logic that describes the types of command objects that it can handle, and how
to pass off those that it cannot handle to the next processing object in the
chain. A mechanism also exists for adding new processing objects to the end of
this chain.
In
writing an application of any kind, it often happens that the event generated
by one object needs to be handled by another one. And, to make our work even
harder, access can be denied to the object which needs to handle
the event. In this case there are two possibilities: there is the beginner/lazy
approach of making everything public, creating reference to every object and
continuing from there and then there is the expert approach of using the Chain
of Responsibility.
The
Chain of Responsibility design pattern allows an object to send a command
without knowing what object will receive and handle it. The request is sent
from one object to another making them parts of a chain and each object in this
chain can handle the command, pass it on or do both. The most usual example of
a machine using the Chain of Responsibility is the vending machine coin slot:
rather than having a slot for each type of coin, the machine has only one slot
for all of them. The dropped coin is routed to the appropriate storage place
that is determined by the receiver of the command.
● Intent: It avoids attaching the sender of a request to its receiver, giving this way other objects the possibility of handling the request too.
● The objects become parts of a chain and the request is
sent from one object to another across the chain until one of the objects will
handle it.
This pattern promotes the idea of loose coupling, which is
considered a programming best practice.
View Helper: When processing logic is embedded inside the
controller or view, it causes code duplication in all the pages. This causes
maintenance problems, as any change to piece of logic has to be done in all the
views. In the view helper pattern the view delegates its processing
responsibilities to its helper classes. The helper classes JavaBeans are used
to compute and store the presentation data and Custom Tags are used for
computation of logic and displaying them iteratively complement each other.
Service to Worker and Dispatcher View: These two patterns are a
combination of Front Controller and View Helper patterns with a dispatcher
component. One of the responsibilities of a Front Controller is choosing a view
and dispatching the request to an appropriate view. This behavior can be partitioned
into a separate component known as a dispatcher. But these two patterns differ
in the way they suggest different division of responsibility among the
components.
Service to Worker
|
Dispatcher View
|
Combines the
front controller and dispatcher, with views and view helpers to handle client
requests and dynamically prepares the response.
● Controllers delegate the content retrieval to the
view helpers, which populates the intermediate model content for the view.
● Dispatcher is responsible for the view management and
view navigation.
|
Similar to
service to worker but the emphasis is on a different usage pattern. This
combines the Front controller and the dispatcher with the view helpers but
● Controller does not delegate content retrieval to
view helpers because this activity is deferred to view processing.
● Dispatcher is responsible for the view management and
view navigation.
|
Promotes
more up-front work by the front controller and dispatcher for the
authentication, authorization,
content
retrieval, validation, view management and navigation.
|
Relatively
has a lightweight front controller and dispatcher with minimum functionality
and most of the work is done by the view.
|
Proxy Design Pattern: Provides a surrogate or placeholder for
another object to control access to it. Proxy object acts as an intermediary
between the client and target object.
The proxy object has the same
interface as the target object. The proxy object holds reference to the
target object. There are different types of proxies:
● Remote Proxy: Provides a reference
to an object, which resides in a separate address space. e.g. RMI, CORBA
etc (RMI stubs acts as a proxy for the skeleton objects.)
● Virtual Proxy: Allows the creation
of memory intensive objects on demand. The target object will not be created
until it is really needed.
● Access Proxy: Provides different
clients with different access rights to the target object.
Ex: In Hibernate
framework, lazy loading of persistent objects are facilitated by virtual proxy
pattern. Say you have a Department object, which has a collection of Employee
objects. Let’s say that Employee objects are lazy loaded. If you make a call to
dept.getEmployees(), then Hibernate will load only the employeeIDs and the
version numbers of the Employee objects, thus saving loading of individual
objects until later. So what you really have is a collection of proxies not the
real objects. The reason being, if you have hundreds of employees for a
particular department then chances are good that you will only deal with only a
few of them. So, why unnecessarily instantiate all the Employee objects? This
can be a big performance issue in some situations. So when you make a call on a
particular employee i.e. employee.getName() then the proxy loads up the real object from the database.
Adapter Design Pattern: Its like drivers. OS never speaks to hardware;
it always speak to drivers. If a new hardware is coming, OS needs driver to make use of hardware.
Ex: Action class uses the Adapter design pattern. Action class is a wrapper around the business logic. The purpose of Action class is to translate the HttpServletRequest to the business logic. To use the Action class, subclass it and overwrite the execute() method. The actual business logic should be in a separate package to allow reuse of business logic in a protocol independent manner.
Ex: Action class uses the Adapter design pattern. Action class is a wrapper around the business logic. The purpose of Action class is to translate the HttpServletRequest to the business logic. To use the Action class, subclass it and overwrite the execute() method. The actual business logic should be in a separate package to allow reuse of business logic in a protocol independent manner.
As the name might
suggest, this design pattern is used where an unrelated class having a different
interface is required to accept calls to the methods which are actually part of
some other class having a different interface. There are the two ways to
achieve this - Interfaces and Composition. Suppose we have two classes A and B
and we would like to have an instance of the type A to accept calls to the
methods of class B. In that case, using inheritance we can derive a sub-class (say C)
from A and add those methods of Class B into the new sub-class C so that they
can be called on an instance of class C which will of course be of type A. Using
composition we can simply have a new class which will have the original
non-compliant class as a member and we'll add the required methods in this new
class to internally call the corresponding methods of the non-compliant member
class.
Prototype Design Pattern: This design pattern is used in
cases where the instance creation of the class is very complex and/or time
consuming. So, instead of creating new objects every time we copy the already
existing original instance and modify the properties of that instance as
required.
Ex: Suppose you have
created an object by executing many time consuming database queries and if the
new objects can be constructed by modifying the queried data, then you would
certainly not like to fire all the queries all over again to create new
objects. Instead copying the original instance and modifying the copied data to
suit the requirements of the new report will be a better option here.
Object Pool: To prevent creating and destroying the objects
each and every time. It's used when creation and destruction is costly.
Mediator Design Pattern: Used for delegation among various
objects.
Visitor Design Pattern: It uses a call back
mechanism. It's used when we want to more loose coupling. Visitor pattern
makes adding new operations in an easy manner which affect a class hierarchy
without having to change any of the classes in the hierarchy. The visitor
pattern allows you to manipulate a collection of polymorphic objects without
the messy and unmaintainable typecasts and instanceof operations.
Ex: We can add a GoodsDebugVisitor
class to have the visitor just print out some debug information about each item
visited etc. In fact, you can write any number of visitor classes for the Goods
hierarchy e.g. GoodsLabellingVisitor, GoodsPackingVisitor etc.
Bridge Design Pattern: Break multi-dimension inheritance into
single dimension inheritance, so that both can vary independently. It's
called bridge because client uses only one implementation (dimension) and
others are hidden by it.
Bridge design pattern is used to achieve the very
basic purpose of OO Programming, which is to separate of a class
from its implementation. This approach has the obvious advantage of achieving
the flexibility of being able to alter the implementation any time one
wants to without affecting the client code using the class.
Sounds similar
to the Adapter Design Pattern, but the intent is quite different. The
Adapter Design Pattern is used to enable the interfaces of one or more
classes to look like and be compatible to the interface of a particular
class whereas in case Bridge Design Pattern the class is designed in such a way
that the interface is fixed and separate from the implementation. Here we
separate the interface of a class from its implementation so that we can have
the liberty of distributing the interface to be used by clients without
being tightly tied to a particular implementation. Any future changes in
the implementation won't affect the client code and this requirement can
be really crucial in some cases.
Ex: If the class
is being used to display some data, then in future the revised implementation
may be used provide additional details/graphs. This will only require to
replace the older implementation with the newer one.
How can we implement
this design pattern? Very simple... by just having an interface and
subsequently implementing the interface in one or more classes. We of
course need to have a fixed interface otherwise the very purpose of this
design pattern to provide the flexibility of having a loosely coupled implementation
won't be achieved.
State Design Pattern: Logic varies with state.
Service Locator Design Pattern: J2EE makes use of the JNDI
interface to access different resources like JDBC, JMS, EJB etc. The client
looks up for these resources through the JNDI look-up. The JNDI look-up is
expensive because the client needs to get a network connection to the server
first. So this look-up process is expensive and redundant. To avoid this
expensive and redundant process, service objects can be cached when a client
performs
the JNDI look-up for
the first time and reuse that service object from the cache for the subsequent
look-ups. The service locator pattern implements this technique.
Facade Design Pattern: It acts as a gateway. To control the
entry and exit into the system, we use facade pattern. It can only exist
outside the system. It can't exist inside. This aims to minimize network calls
between server and client by replacing fine grained calls with coarse grained
call.
Value object J2EE design pattern: Avoids fine-grained method calls
by creating a value object which will help the client to make a coarse-grained
call.
Fast-lane reader J2EE design pattern: Access the persistence layer
directly using a DAO (Data Access Object) pattern instead of using entity
beans.
Creator Vs Factory:
Former has a static creator method. It is used to create an object out of
single family class. However, when requirement is to create 2 or more
objects like DAO object and business object, belonging to different class
families, you should use a factory pattern.
Strategy Vs Command:
In former, strategy is chosen by consumer. In latter, consumer is
unaware of it. He will just call execute and apt command will be executed.
Decorator Vs Chain of responsiblity:
In former, all
runs whereas in latter, only one runs. We delegate and find the current one.
Adapter Vs Proxy:
Both are wrappers. Former changes the structure or signature, whereas latter
doesn't. In a situation, both can be applied. It just depends on
your requirements. If you don't want to expose the structure or
signatures can be changed in future, use the former, otherwise latter. Proxy has the same interface as original
object whereas adapter has different interface.
Decorator Vs Proxy
The main intent of the decorator pattern is to
enhance the functionality of the target object whereas the main intent of the
proxy pattern is to control access to the target object.
MVC1 Vs MVC2 (or known as Model2 architecture)
Struts can implement Model 1 and Model
2. Model 2 most properly describes the application of MVC in a Web-Application
context.
Following are the important features of
MVC1 architecture:
1. HTML or JSP files are used to code the presentation.
JSP files use java beans to retrieve data if required.
2. MVC1 architecture is page centric design.
3. Data access is usually done using Custom tag or through
java bean call. Therefore we can say that in MVC1 there is tight coupling
between page and model.
Following are the important features of MVC2 architecture:
1. This architecture removes the page centric property of
MVC1 architecture by separating Presentation, Control logic and Application
state.
2. In MVC2 architecture, there is one Controller which
receives all requests for the application and is responsible for taking
appropriate action in response to each request. Second one is Model which is
represented by JavaBeans, business object, and database. Third one is view (ex: JSP page), it takes the information provided by Controller and Module and
presents it to user.
MVC1 Architecture has Model part as classes, (ex: Bean
classes for connectivity of Database), View part as jsp pages and here only one
controller Servlet is used. Here, we send request from browser by jsp page which goes to servlet(controller). Servlet (directly)
fetches information from classes(Models) according to the request and give
response to the view part (Jsp Page).
In MVC2 Architecture, we use Open Source Struts FrameWork. Here Browser sends HTTP request to the ActionServlet that reads StrutsConfig.XML (these two play role of Controller), then it goes to Model part according to request by Browser. Here in Action part, we have database, ActionForm(Basicly Beans or EJB) and that give a response to View Part As Jsp Page to the Browser.
In MVC2 Architecture, we use Open Source Struts FrameWork. Here Browser sends HTTP request to the ActionServlet that reads StrutsConfig.XML (these two play role of Controller), then it goes to Model part according to request by Browser. Here in Action part, we have database, ActionForm(Basicly Beans or EJB) and that give a response to View Part As Jsp Page to the Browser.
The main difference between Model 1 and Model 2 is that in
Model 2, a controller handles the user request instead of another JSP. The
controller is implemented as a Servlet. MVC1
combines the presentation logic with the business logic where as MVC2 it separates the presentation logic from business logic
MVC1 (Model 1) = JSP as "V" and "C",
JavaBean as "M"
MVC2 (Model 2) = Servlet as "C", JSP as
"V", JavaBean as "M"
JSP and Servlets both are the server side components which can
respond to the client request. But JSP is a scripting language flexible for web
designers to use the tags with java language. It is basically used for
presentation.
In Servlet, the request and response object is passed onto
different servlets with little task completed by each servlet. This controlling
part is easier to write in java. As Servlet contains the pure java code and
coding is needed to generate the proper user response. So Servlet is needed.
With MVC you can have as many controller servlets in your web
application as you want. In fact you can have one Controller Servlet per module. However
there are several advantages of having a single controller servlet for the
entire web application. If you have several controller servlets, chances are
that you have to duplicate the logic for tasks like logging, authorization,
security etc in all those places. A single controller servlet for the web
application lets you centralize all the tasks in a single place. Elegant code
and easier to maintain.
Web applications based on Model 2 architecture are easier to
maintain and extend since the views do not refer to each other and there is no
presentation logic in the views. It also allows you to clearly define the roles
and responsibilities in large projects thus allowing better coordination among
team members.
No comments:
Post a Comment