Skip to content

Instantly share code, notes, and snippets.

@cardasac
Last active May 10, 2019 21:30
Show Gist options
  • Save cardasac/0b2465641a299687155d4ea5e3290068 to your computer and use it in GitHub Desktop.
Save cardasac/0b2465641a299687155d4ea5e3290068 to your computer and use it in GitHub Desktop.
SE-2016

1.

a)

The authors claim the following as advantages of interfaces over implementation:

  • clients remain unaware of the specific types of objects they use, as long as the object adheres to the interface
  • clients remain unaware of the classes that implement these objects; clients only know about the abstract class(es) defining the interface

Use of an interface also leads to dynamic binding and polymorphism, which are central features of object-oriented programming.

The authors refer to inheritance as white-box reuse, with white-box referring to visibility, because the internals of parent classes are often visible to subclasses. In contrast, the authors refer to object composition (in which objects with well-defined interfaces are used dynamically at runtime by objects obtaining references to other objects) as black-box reuse because no internal details of composed objects need be visible in the code using them.

The authors discuss the tension between inheritance and encapsulation at length and state that in their experience, designers overuse inheritance (Gang of Four 1995:20). The danger is stated as follows:

"Because inheritance exposes a subclass to details of its parent's implementation, it's often said that 'inheritance breaks encapsulation'". (Gang of Four 1995:19)

They warn that the implementation of a subclass can become so bound up with the implementation of its parent class that any change in the parent's implementation will force the subclass to change. Furthermore, they claim that a way to avoid this is to inherit only from abstract classes—but then, they point out that there is minimal code reuse.

Using inheritance is recommended mainly when adding to the functionality of existing components, reusing most of the old code and adding relatively small amounts of new code.

b)

Design patterns

In software engineering, a software design pattern is a general, reusable solution to a commonly occurring problem within a given context in software design. It is not a finished design that can be transformed directly into source or machine code. It is a description or template for how to solve a problem that can be used in many different situations. Design patterns are formalized best practices that the programmer can use to solve common problems when designing an application or system.

Object-oriented design patterns typically show relationships and interactions between classes or objects, without specifying the final application classes or objects that are involved. Patterns that imply mutable state may be unsuited for functional programming languages, some patterns can be rendered unnecessary in languages that have built-in support for solving the problem they are trying to solve, and object-oriented patterns are not necessarily suitable for non-object-oriented languages.

Design patterns may be viewed as a structured approach to computer programming intermediate between the levels of a programming paradigm and a concrete algorithm.

Adapter

Check 2017

2.

a)

Check 2018

b)

Check 2018

Specific answer for generic situations

Strong vs. Weak reference

The observer pattern can cause memory leaks, known as the lapsed listener problem, because in basic implementation it requires both explicit registration and explicit deregistration, as in the dispose pattern, because the subject holds strong references to the observers, keeping them alive. This can be prevented by the subject holding weak references to the observers.

Coupling and typical pub-sub implementations

Typically the observer pattern is implemented with the "subject" (which is being "observed") being part of the object, whose state change is being observed, to be communicated to the observers upon occurrence. This type of implementation is considered "tightly coupled", forcing both the observers and the subject to be aware of each other and have access to their internal parts, creating possible issues of scalability, speed, message recovery and maintenance (also called event or notification loss), the lack of flexibility in conditional dispersion and possible hindrance to desired security measures. In some (non-polling) implementations of the publish-subscribe pattern (also called the pub-sub pattern), this is solved by creating a dedicated "message queue" server and at times an extra "message handler" object, as added stages between the observer and the observed object whose state is being checked, thus "decoupling" the software components. In these cases, the message queue server is accessed by the observers with the observer pattern, "subscribing to certain messages" knowing only about the expected message (or not, in some cases), but knowing nothing about the message sender itself, and the sender may know nothing about the receivers. Other implementations of the publish-subscribe pattern, which achieve a similar effect of notification and communication to interested parties, do not use the observer pattern altogether.

Still, in early implementations of multi-window operating systems like OS/2 and Windows, the terms "publish-subscribe pattern" and "event driven software development" were used as a synonym for the observer pattern.

The observer pattern, as described in the GoF book, is a very basic concept and does not deal with observance removal or with any conditional or complex logic handling to be done by the observed "subject" before or after notifying the observers. The pattern also does not deal with recording the "events", the asynchronous passing of the notifications or guaranteeing they are being received. These concerns are typically dealt with in message queueing systems of which the observer pattern is only a small part.

Related patterns: Publish–subscribe pattern, mediator, singleton.

Package diagram

Sequence Diagram

Observer pattern

Check 2017

3.

a)

context BookingSystem::makeReservation(r : Reservation, c : Customer, t : Table)
	pre preCond1: r.isDefined()
	pre preCond2: c.isDefined()
	pre preCond3: t.isDefined()
	pre preCond4: booking -> excludes(r)
	pre preCond5: t.booking.getTime() -> excludes(t.bookings.getTime() + 2)
	post postCond1: booking -> includes(r)

b)

USE

-- Class Reservation < Booking (generalisation)
class Reservation < Booking
	attributes

	operations
		setCustomer(c : Customer) 
		begin
			self.customer := c
		end
end
-- Create class Booking --
class Booking 
	attributes
		covers : Integer
		date: Date
		time : Time
	operations

		getTime(t : Time)
		begin
			self.time := t --self.time.hour*60 + self.time.min
		end

		setTime(t : Time)
		begin 
			self.time := t
		end		
end

SOIL

!new Rservation('res1')
!res1.setCustomer('Icaurs')

!new Booking('booking1')
!booking1.covers := 4
!booking1.Time := 120

!booking1.getTime()

c)

Check 2018

4.

Check 2018

5.

Check 2018

@cardasac
Copy link
Author

cardasac commented May 9, 2019

Analysis class model

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment