Complex classes like NullStorage often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use NullStorage, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 25 | class NullStorage extends Common { |
||
| 26 | public function __construct($parameters) { |
||
| 29 | |||
| 30 | public function getId() { |
||
| 33 | |||
| 34 | public function mkdir($path) { |
||
| 37 | |||
| 38 | public function rmdir($path) { |
||
| 41 | |||
| 42 | public function opendir($path) { |
||
| 45 | |||
| 46 | public function is_dir($path) { |
||
| 49 | |||
| 50 | public function is_file($path) { |
||
| 53 | |||
| 54 | public function stat($path) { |
||
| 57 | |||
| 58 | public function filetype($path) { |
||
| 61 | |||
| 62 | public function filesize($path) { |
||
| 65 | |||
| 66 | public function isCreatable($path) { |
||
| 69 | |||
| 70 | public function isReadable($path) { |
||
| 73 | |||
| 74 | public function isUpdatable($path) { |
||
| 77 | |||
| 78 | public function isDeletable($path) { |
||
| 81 | |||
| 82 | public function isSharable($path) { |
||
| 85 | |||
| 86 | public function getPermissions($path) { |
||
| 89 | |||
| 90 | public function file_exists($path) { |
||
| 93 | |||
| 94 | public function filemtime($path) { |
||
| 97 | |||
| 98 | public function file_get_contents($path) { |
||
| 101 | |||
| 102 | public function file_put_contents($path, $data) { |
||
| 105 | |||
| 106 | public function unlink($path) { |
||
| 109 | |||
| 110 | public function rename($path1, $path2) { |
||
| 113 | |||
| 114 | public function copy($path1, $path2) { |
||
| 117 | |||
| 118 | public function fopen($path, $mode) { |
||
| 121 | |||
| 122 | public function getMimeType($path) { |
||
| 125 | |||
| 126 | public function hash($type, $path, $raw = false) { |
||
| 129 | |||
| 130 | public function free_space($path) { |
||
| 133 | |||
| 134 | public function touch($path, $mtime = null) { |
||
| 137 | |||
| 138 | public function getLocalFile($path) { |
||
| 141 | |||
| 142 | public function hasUpdated($path, $time) { |
||
| 145 | |||
| 146 | public function getETag($path) { |
||
| 149 | |||
| 150 | public function isLocal() { |
||
| 153 | |||
| 154 | public function getDirectDownload($path) { |
||
| 157 | |||
| 158 | public function copyFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) { |
||
| 161 | |||
| 162 | public function moveFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) { |
||
| 165 | |||
| 166 | public function test() { |
||
| 169 | |||
| 170 | public function getOwner($path) { |
||
| 173 | |||
| 174 | public function getCache($path = '', $storage = null) { |
||
| 177 | } |
||
| 178 |
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.
Let’s take a look at an example:
Our function
my_functionexpects aPostobject, and outputs the author of the post. The base classPostreturns a simple string and outputting a simple string will work just fine. However, the child classBlogPostwhich is a sub-type ofPostinstead decided to return anobject, and is therefore violating the SOLID principles. If aBlogPostwere passed tomy_function, PHP would not complain, but ultimately fail when executing thestrtouppercall in its body.