- All codes are written by Kotlin.
- This repository contains about 20 standard design patterns by GoF, and other design patterns such as Repository, Null Object, Transfer Object + DAO, Intercepting Filter, etc.
- Some design patterns used (or can be used) in MyFiles (you can see it in in_myfiles package). Some are not used currently, so I put it in examples package.
- All patterns are classified into each package with its correct type (Creational, Structural, Behavioral).
- Some design patterns was not implemented, because I am quite lazy in this time. So I refered link from reliable sources that I think are easy to understand for you to learn more about. The reference links I attached in header comment each of
Main.kt
file. - Most of the design patterns mentioned here come with UML. I drew it with PlantUML. For a more detailed overview, visit PlantUML Official Website.
Includes design patterns to instantiate objects in different ways.
- Singleton: Create instance of object just once and use it throughout the application. This has two ways to implement (
eager-initialization
andlazy-initialization
), but in this project, I only implementlazy-inititalization
to simulate search queries from different sources (LOCAL
,CLOUD
) but only initialize a singleSearchDataSource
object (singleton). - Factory method: Encapsulate object creation with a common base class. I have simulated it for setting the sort for list file info by name, extension, size or time (factory_method).
- Abstract factory: Encapsulates object creation and allows for the creation of many different types of objects. In MyFiles, it has two versions of app (one for global market, one for China market). Along with that are different ways to display items on the home page such as Trash, Cloud, etc. These items all inherit HomeItem. Therefore, I have created 2 factories for these 2 markets, each factory will be responsible for creating each individual home item (abstract_factory).
- Builder: Separate the construction of a complex object from its representation so that the same construction process can create different representations. In this project, it is described as creating a dialog builder and setting parameters such as title, message, positive, neutral and negative button for dialog (builder).
- Prototype: Used to copy an object from an existing object. I implemented it as creating a
GroupHeaderInfo
from an existingFileInfo
object by just adding an extension methodmakeGroupHeader
and changing theisGroupHeader
value of the FileInfo object (prototype).
Includes design patterns for connecting objects and expanding the system.
- Adapter: Allows objects with incompatible interfaces to collaborate by converting the interface of one class to an interface of another class. This pattern is used a lot in Android programming, especially the
RecyclerView
part. I just created a simple example of a language translator to illustrate it well. Here,TranslatorAdapter
will contain the interface of the source objectJapaneseTranslator
.Client
will send text toTranslatorAdapter
,TranslatorAdapter
will receive, perform translation and forward it toJapaneseTranslator
(adapter). - Bridge: Creating bridges between different layers aims to separate the implementation, allowing the layers to change independently of each other. An example exists in MyFiles where each component uses a variety of resources (
string
,drawable
,dimen
,color
). However, this makes identifying the resource components of each object unclear. MyFiles has grouped these common properties based on the nature of theBridge pattern
- dividingAbstraction
into objects used by the client such asDefaultRes
(generic resource, default or ungrouped),HomeRes
(resources on the home page),StorageRes
(resources for storage components likeLocal Internal
,SD Card
, etc.),CloudRes
(resources for cloud content), etc. andInterface
are extensions of resources such asstring
,drawable
,dimen
,color
. An intermediate classResourceBridge
will have the role of interacting with these two parts (bridge). - Composite: Combine classes together to avoid having to inherit or implement too many classes and interfaces. A simple example is calculating the size of a folder. We instantiate
DirectoryFileInfo
which inherits theFileInfo
interface and overrides itsgetSize
method.DirectoryFileInfo
will become a typeFileInfo
, passed as a parameter a list of files in thatfolder
. When client calls itsgetSize
function, it will return the total size of the entire folder (composite). - Decorator: Lets you attach new behaviors to objects by placing these objects inside special wrapper objects that contain the behaviors. In this example, we want to perform some additional features such as downloading before copying the file, but the current operators do not allow that. Therefore, we create a
DecoratorOperation
class that inherits the currentIFileOperation
behavior, receives an instance fromIFileOperation
(the current operation) and adds adoExtraOperation
method before executing the nextdoOperation
from the instance there. TheDownloadOperation
subclass will extendDecoratorOperation
and implement additional methods indoExtraOperation
(decorator). - Flyweight: Lets you add more objects into the available amount of memory by sharing common parts of state between multiple objects instead of keeping all the data in each object. For example, if object
A
contains objectB
(immutable) and objectC
(mutable), we can initialize objectB
once and store it incache
. Next time, if we init new objectA
, we just need to use the previously cached objectB
instead of creating a new one. This saves significantly on generated memory. I have clearly described this pattern through two examples of initializingFileInfoGenerator
in file_generator andPageSpec
in page_spec. - Proxy: Lets you provide a substitute or placeholder for another object. A proxy controls access to the original object, allowing you to perform something either before or after the request gets through to the original object. This pattern is very useful when you need to prevent or check a certain condition, or reduce the number of concurrent object instantiations before reaching the root object. In this example, I have simulated downloading thumbnails from the cloud. By creating a
CachedThumbnail
object to check for the existence of a thumbnail before downloading it inDownloadThumbnail
, this will help reduce the number of redundant thumbnail downloads (proxy).
Includes design patterns used to process data and events that occur during program operation.
- Chain of Responsibility: Allows you to pass requests along a chain of handlers. Upon receiving a request, each handler decides to process the request or pass it on to the next handler in the chain. An example that appeared in MyFiles 2016 - 2018 (Android Oreo OS), is that the display of home items such as
LocalStorageItem
,RecentItem
,CategoryItem
,AnalyzeStorageItem
is executed and loaded in chain form (chain_of_responsibility). - Command: Process the action according to the corresponding command.
- Facade: Provides a simplified interface to a library, framework, or any other complex set of classes.
- Observer: Allows you to define a subscription mechanism to notify multiple objects about any event that occurs to the object they are observing.
As for these three design patterns (Facade, Command, Observer), in MyFiles they are used in combination. Here,
Facade
acts asMenuExecuteManager
to encapsulate complex processing methods inside.Command
is a descendant ofAbsExecute
.Observer
is a procedure that registers to receive results returned byResultListener
via theaddDataCallbackListener
method (facade_and_command_and_observer).
- Strategy: Separate the part that handles a specific function from the object. Then create a set of algorithms to handle that function and choose which algorithm we find most appropriate when executing the program. It's like the same sort function but there will be many different sorting strategies such as
QuickSort
,MergeSort
, etc. The clearest example in MyFiles is the way list display types are divided based onBehaviorType
. There are three display types:DefaultListBehavior
(default type),ExpandableListBehavior
(display type that includes group headers),CustomListBehavior
(display type with expanded header detailed inAnalyzeStorageFileListPage
). Depending on theBehaviorType
definition, select the corresponding list display type (strategy). - State: Allows an object to change its behavior when its internal state changes. To illustrate, I give a typical example in the MVI architecture style. Here, I use
UiState
to notifyHomePageController
the appropriate states to update the data. The special thing about usingUiState
as a sealed class instead of usingconstant variable
orenum class
states is that it can carry return data or exception messages attached for the client to call. and use it directly (state). - Template method: Define the framework of the algorithm in a superclass but allow subclasses to override specific steps of the algorithm without changing its structure. It is similar to the
onCreate
,onStart
,onPause
, etc. functions in the lifecycle ofActivity
. Here I have an illustrative example (not in MyFiles) so you understand how it works. APageTemplate
will show components in the given order (showHeader
,showBody
,showFooter
,showNavigation
). However, on different pages such asContactPage
orHomePage
, there will be differentshowBody
methods. We will just re-implement this method fromPageTemplate
without changing the display order of the components (template_method). - Iterator: Used to iterate over a set, similar to how you use a loop to traverse a list. Here the example is very simple, you let your object inherit
Iterable
and create itsIterator
instance. TheDirectoryIterator
object will then be capable of sequential traversal (iterator).
Includes other design patterns for tasks such as data stream processing, database queries, exception prevention, etc.
- Null object: Provides an alternative handling solution when the returned result is not in the given set. To illustrate, I added
NonNullFileOperation
to handle when the get file operation fromFileOpeationFactory
is null (null_object). - Repository: Separate the Business Logic and Data Access (database) layers from each other, as an intermediate layer between data access and logic processing. It helps make data access more strict and secure. I described it the way MyFiles is using it, which is to create interfaces or abstract classes SearchRepository to bridge communication from the business logic layer (
SearchController
) and data access layer (SearchDataSource
) (repository). - Intercepting filter: Used when you want to do some processing before (pre-processing) when the request is processed by the target application (target) or after (post-processing) when the response is returned from the target (commonly used in Java EE). Here, I have described it as a filter operator on the data stream. It will filter and remove invalid files through the
VerifyHiddenFileFilter
andVerifyLocalStorageFileFilter
filters (intercepting_filter). - Data access object (DAO): Used to separate data storage logic in a separate layer. Instead of having logic that communicates directly with the database, file system, web service, or whatever storage mechanism the application needs to use, we'll let this logic communicate with the DAO middle layer. . This DAO layer then communicates with the storage system and database management system such as performing tasks related to storing and querying data (searching, adding, deleting, editing, etc.). The example here is very simple, I have created the
FileSystemDao
class to mediate communication between 2 different data types sources. The business logic layerLocalFileRepository
will perform getting pure data fromFileSystemDataSource
throughFileSystemDao
and converting it to the data type you want without directly affectingFileSystemDataSource
. (data_access_object).
This is a project that I created to practice design skills based on design patterns. Therefore, the knowledge and implementation in this is based on my personal knowledge and experience. I would be happy if you could contribute other implementations, or newer design patterns. Thank you.